├── packages ├── openapi_generator_flutter │ ├── .github │ ├── ios │ │ ├── Runner │ │ │ ├── Runner-Bridging-Header.h │ │ │ ├── Assets.xcassets │ │ │ │ ├── LaunchImage.imageset │ │ │ │ │ ├── LaunchImage.png │ │ │ │ │ ├── LaunchImage@2x.png │ │ │ │ │ ├── LaunchImage@3x.png │ │ │ │ │ ├── README.md │ │ │ │ │ └── Contents.json │ │ │ │ └── AppIcon.appiconset │ │ │ │ │ ├── Icon-App-20x20@1x.png │ │ │ │ │ ├── Icon-App-20x20@2x.png │ │ │ │ │ ├── Icon-App-20x20@3x.png │ │ │ │ │ ├── Icon-App-29x29@1x.png │ │ │ │ │ ├── Icon-App-29x29@2x.png │ │ │ │ │ ├── Icon-App-29x29@3x.png │ │ │ │ │ ├── Icon-App-40x40@1x.png │ │ │ │ │ ├── Icon-App-40x40@2x.png │ │ │ │ │ ├── Icon-App-40x40@3x.png │ │ │ │ │ ├── Icon-App-60x60@2x.png │ │ │ │ │ ├── Icon-App-60x60@3x.png │ │ │ │ │ ├── Icon-App-76x76@1x.png │ │ │ │ │ ├── Icon-App-76x76@2x.png │ │ │ │ │ ├── Icon-App-1024x1024@1x.png │ │ │ │ │ ├── Icon-App-83.5x83.5@2x.png │ │ │ │ │ └── Contents.json │ │ │ ├── AppDelegate.swift │ │ │ ├── Base.lproj │ │ │ │ ├── Main.storyboard │ │ │ │ └── LaunchScreen.storyboard │ │ │ └── Info.plist │ │ ├── Flutter │ │ │ ├── Debug.xcconfig │ │ │ ├── Release.xcconfig │ │ │ └── AppFrameworkInfo.plist │ │ ├── Runner.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ │ ├── WorkspaceSettings.xcsettings │ │ │ │ └── IDEWorkspaceChecks.plist │ │ ├── Runner.xcodeproj │ │ │ ├── project.xcworkspace │ │ │ │ ├── contents.xcworkspacedata │ │ │ │ └── xcshareddata │ │ │ │ │ ├── WorkspaceSettings.xcsettings │ │ │ │ │ └── IDEWorkspaceChecks.plist │ │ │ └── xcshareddata │ │ │ │ └── xcschemes │ │ │ │ └── Runner.xcscheme │ │ ├── .gitignore │ │ └── Podfile │ ├── web │ │ ├── favicon.png │ │ ├── icons │ │ │ ├── Icon-192.png │ │ │ └── Icon-512.png │ │ ├── manifest.json │ │ └── index.html │ ├── android │ │ ├── gradle.properties │ │ ├── app │ │ │ ├── src │ │ │ │ ├── main │ │ │ │ │ ├── res │ │ │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ │ ├── drawable │ │ │ │ │ │ │ └── launch_background.xml │ │ │ │ │ │ └── values │ │ │ │ │ │ │ └── styles.xml │ │ │ │ │ ├── kotlin │ │ │ │ │ │ └── com │ │ │ │ │ │ │ └── example │ │ │ │ │ │ │ └── openapi_generator_flutter │ │ │ │ │ │ │ └── MainActivity.kt │ │ │ │ │ └── AndroidManifest.xml │ │ │ │ ├── debug │ │ │ │ │ └── AndroidManifest.xml │ │ │ │ └── profile │ │ │ │ │ └── AndroidManifest.xml │ │ │ └── build.gradle │ │ ├── gradle │ │ │ └── wrapper │ │ │ │ └── gradle-wrapper.properties │ │ ├── .gitignore │ │ ├── settings.gradle │ │ └── build.gradle │ ├── README.md │ ├── .gitignore │ ├── .metadata │ ├── test │ │ └── widget_test.dart │ ├── analysis_options.yaml │ ├── pubspec.yaml │ └── lib │ │ └── main.dart ├── openapi_base │ ├── lib │ │ ├── src │ │ │ ├── util │ │ │ │ ├── internal_utils.dart │ │ │ │ ├── shelf_cookie │ │ │ │ │ ├── shelf_cookie.dart │ │ │ │ │ └── cookie_parser.dart │ │ │ │ └── uuid.dart │ │ │ ├── http_headers.dart │ │ │ ├── server │ │ │ │ ├── openapi_server_base.dart │ │ │ │ ├── openapi_shelf_noop_server.dart │ │ │ │ ├── stoppable_process.dart │ │ │ │ └── openapi_shelf_server.dart │ │ │ ├── openapi_content_type.dart │ │ │ ├── openapi_exception.dart │ │ │ ├── openapi_base.dart │ │ │ └── openapi_client_base.dart │ │ └── openapi_base.dart │ ├── example │ │ └── README.md │ ├── .idea │ │ ├── dictionaries │ │ │ └── herbert.xml │ │ ├── vcs.xml │ │ └── codeStyles │ │ │ └── Project.xml │ ├── README.md │ ├── .gitignore │ ├── analysis_options.yaml │ ├── pubspec.yaml │ ├── LICENSE │ ├── CHANGELOG.md │ └── pubspec.lock └── openapi_code_builder │ ├── _docs │ ├── screenshot.png │ ├── screenshot_client.png │ └── screenshot_server.png │ ├── .idea │ ├── dictionaries │ │ └── herbert.xml │ ├── codeStyles │ │ ├── codeStyleConfig.xml │ │ └── Project.xml │ ├── vcs.xml │ └── runConfigurations │ │ ├── example_build_runner_build.xml │ │ ├── build_runner.xml │ │ └── build_runner_build.xml │ ├── example │ ├── README.md │ ├── pubspec.yaml │ ├── bin │ │ ├── example_client.dart │ │ └── example_server.dart │ ├── lib │ │ └── src │ │ │ └── api │ │ │ ├── testapi.openapi.g.dart │ │ │ ├── testapi.openapi.yaml │ │ │ └── petstore.openapi.g.dart │ ├── analysis_options.yaml │ └── pubspec.lock │ ├── build.yaml │ ├── .gitignore │ ├── testapi_array.openapi.yaml │ ├── lib │ ├── openapi_code_builder.dart │ └── src │ │ └── custom_allocator.dart │ ├── pubspec.yaml │ ├── LICENSE │ ├── bin │ └── openapi_code_builder_cli.dart │ ├── CHANGELOG.md │ ├── README.md │ ├── analysis_options.yaml │ └── pubspec.lock ├── .gitignore ├── .gitmodules ├── README.md └── .github └── workflows └── flutter-gh-pages.yaml /packages/openapi_generator_flutter/.github: -------------------------------------------------------------------------------- 1 | ../../.github -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .dart_tool 2 | .packages 3 | playground.dart 4 | -------------------------------------------------------------------------------- /packages/openapi_base/lib/src/util/internal_utils.dart: -------------------------------------------------------------------------------- 1 | T identity(T id) => id; 2 | -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /packages/openapi_code_builder/_docs/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpoul/openapi_dart/HEAD/packages/openapi_code_builder/_docs/screenshot.png -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/web/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpoul/openapi_dart/HEAD/packages/openapi_generator_flutter/web/favicon.png -------------------------------------------------------------------------------- /packages/openapi_code_builder/_docs/screenshot_client.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpoul/openapi_dart/HEAD/packages/openapi_code_builder/_docs/screenshot_client.png -------------------------------------------------------------------------------- /packages/openapi_code_builder/_docs/screenshot_server.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpoul/openapi_dart/HEAD/packages/openapi_code_builder/_docs/screenshot_server.png -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/web/icons/Icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpoul/openapi_dart/HEAD/packages/openapi_generator_flutter/web/icons/Icon-192.png -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/web/icons/Icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpoul/openapi_dart/HEAD/packages/openapi_generator_flutter/web/icons/Icon-512.png -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.enableR8=true 3 | android.useAndroidX=true 4 | android.enableJetifier=true 5 | -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "deps/open-api-dart"] 2 | path = deps/open-api-dart 3 | url = ../open-api-dart.git 4 | [submodule "deps/dart-codable"] 5 | path = deps/dart-codable 6 | url = ../dart-codable 7 | -------------------------------------------------------------------------------- /packages/openapi_base/example/README.md: -------------------------------------------------------------------------------- 1 | For example usage see the examples in `openapi_code_builder`: 2 | 3 | https://github.com/hpoul/openapi_dart/tree/master/packages/openapi_code_builder/example 4 | 5 | -------------------------------------------------------------------------------- /packages/openapi_base/.idea/dictionaries/herbert.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | openapi 5 | 6 | 7 | -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/README.md: -------------------------------------------------------------------------------- 1 | # openapi_generator_flutter 2 | 3 | An easy web UI to try out [openapi_code_builder](https://github.com/hpoul/openapi_dart/tree/master/packages/openapi_code_builder). 4 | 5 | -------------------------------------------------------------------------------- /packages/openapi_base/README.md: -------------------------------------------------------------------------------- 1 | # openapi_base 2 | 3 | Base (runtime) package for OpenAPI code generator. 4 | See https://github.com/hpoul/openapi_dart/tree/master/packages/openapi_code_builder for details and examples. 5 | -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpoul/openapi_dart/HEAD/packages/openapi_generator_flutter/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpoul/openapi_dart/HEAD/packages/openapi_generator_flutter/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /packages/openapi_code_builder/.idea/dictionaries/herbert.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | openapi 5 | 6 | 7 | -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpoul/openapi_dart/HEAD/packages/openapi_generator_flutter/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpoul/openapi_dart/HEAD/packages/openapi_generator_flutter/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /packages/openapi_code_builder/.idea/codeStyles/codeStyleConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpoul/openapi_dart/HEAD/packages/openapi_generator_flutter/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Dart OpenAPI Code Generator 2 | 3 | Dart implementation to generate (dart) server 4 | stubs and client libraries. 5 | 6 | See [packages/openapi_code_builder/README.md](packages/openapi_code_builder/README.md) for details. 7 | -------------------------------------------------------------------------------- /packages/openapi_base/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpoul/openapi_dart/HEAD/packages/openapi_generator_flutter/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpoul/openapi_dart/HEAD/packages/openapi_generator_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpoul/openapi_dart/HEAD/packages/openapi_generator_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpoul/openapi_dart/HEAD/packages/openapi_generator_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpoul/openapi_dart/HEAD/packages/openapi_generator_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpoul/openapi_dart/HEAD/packages/openapi_generator_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpoul/openapi_dart/HEAD/packages/openapi_generator_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpoul/openapi_dart/HEAD/packages/openapi_generator_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpoul/openapi_dart/HEAD/packages/openapi_generator_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpoul/openapi_dart/HEAD/packages/openapi_generator_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpoul/openapi_dart/HEAD/packages/openapi_generator_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpoul/openapi_dart/HEAD/packages/openapi_generator_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpoul/openapi_dart/HEAD/packages/openapi_generator_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpoul/openapi_dart/HEAD/packages/openapi_generator_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpoul/openapi_dart/HEAD/packages/openapi_generator_flutter/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpoul/openapi_dart/HEAD/packages/openapi_generator_flutter/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpoul/openapi_dart/HEAD/packages/openapi_generator_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpoul/openapi_dart/HEAD/packages/openapi_generator_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/android/app/src/main/kotlin/com/example/openapi_generator_flutter/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.openapi_generator_flutter 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity: FlutterActivity() { 6 | } 7 | -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | 9 | # Remember to never publicly share your keystore. 10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app 11 | key.properties 12 | -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /packages/openapi_code_builder/example/README.md: -------------------------------------------------------------------------------- 1 | This example contains example open api specs and their 2 | respective generated code. 3 | 4 | They can be found at https://github.com/hpoul/openapi_dart/tree/master/packages/openapi_code_builder/example 5 | 6 | * `testapi.openapi.yaml`: A very minimal Hello World example 7 | * `petstore.openapi.yaml`: The pet store example provided by he open api spec. 8 | -------------------------------------------------------------------------------- /packages/openapi_code_builder/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /packages/openapi_code_builder/build.yaml: -------------------------------------------------------------------------------- 1 | builders: 2 | openapi_code_builder: 3 | import: 'package:openapi_code_builder/openapi_code_builder.dart' 4 | builder_factories: ['openapiCodeBuilder'] 5 | build_extensions: {".openapi.yaml": [".openapi.dart"]} 6 | auto_apply: dependents 7 | # build_to: cache 8 | build_to: source 9 | runs_before: ['freezed|freezed', 'json_serializable|json_serializable'] 10 | -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /packages/openapi_base/lib/openapi_base.dart: -------------------------------------------------------------------------------- 1 | export 'src/http_headers.dart'; 2 | export 'src/openapi_base.dart'; 3 | export 'src/openapi_client_base.dart'; 4 | export 'src/openapi_content_type.dart'; 5 | export 'src/openapi_exception.dart'; 6 | export 'src/server/openapi_server_base.dart'; 7 | export 'src/server/openapi_shelf_noop_server.dart' 8 | if (dart.library.io) 'src/server/openapi_shelf_server.dart'; 9 | export 'src/util/uuid.dart'; 10 | -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Flutter 3 | 4 | @UIApplicationMain 5 | @objc class AppDelegate: FlutterAppDelegate { 6 | override func application( 7 | _ application: UIApplication, 8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 9 | ) -> Bool { 10 | GeneratedPluginRegistrant.register(with: self) 11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /packages/openapi_base/lib/src/http_headers.dart: -------------------------------------------------------------------------------- 1 | class OpenApiHttpHeaders { 2 | static const contentType = 'content-type'; 3 | static const userAgent = 'user-agent'; 4 | } 5 | 6 | class OpenApiHttpStatus { 7 | static const success = 200; 8 | static const created = 201; 9 | 10 | static const movedPermanently = 301; 11 | static const found = 302; 12 | 13 | static const badRequest = 400; 14 | static const unauthorized = 401; 15 | static const notFound = 404; 16 | static const conflict = 409; 17 | } 18 | -------------------------------------------------------------------------------- /packages/openapi_base/lib/src/server/openapi_server_base.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | abstract class OpenApiServerBase { 4 | Future startServer({ 5 | String address = 'localhost', 6 | int port = 8080, 7 | SecurityContext? securityContext, 8 | int? backlog, 9 | bool shared = false, 10 | String? poweredByHeader = 'Dart with package:shelf', 11 | }); 12 | } 13 | 14 | abstract class StoppableProcessBase { 15 | Future get exitCode; 16 | Future stop(int exitCode, {String? reason}); 17 | } 18 | -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /packages/openapi_base/.gitignore: -------------------------------------------------------------------------------- 1 | # https://gist.github.com/hpoul/b78f7a1b3cde988f3ce4d12e954367eb 2 | # 3 | # IDEA: Allow some configuration, which is shared across users. 4 | 5 | /.idea/* 6 | !.idea/runConfigurations 7 | !.idea/runConfigurations/* 8 | !.idea/vcs.xml 9 | !.idea/dictionaries 10 | !.idea/dictionaries/* 11 | !.idea/inspectionProfiles/* 12 | !.idea/codeStyles 13 | !.idea/codeStyles/* 14 | *.iml 15 | 16 | # Java/Kotlin/Android 17 | 18 | /.gradle 19 | /build 20 | /out 21 | 22 | # JavaScript/Node.JS 23 | 24 | /node_modules 25 | 26 | #### project specific ignores below 27 | 28 | -------------------------------------------------------------------------------- /packages/openapi_code_builder/.idea/runConfigurations/example_build_runner_build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | -------------------------------------------------------------------------------- /packages/openapi_code_builder/.gitignore: -------------------------------------------------------------------------------- 1 | # https://gist.github.com/hpoul/b78f7a1b3cde988f3ce4d12e954367eb 2 | # 3 | # IDEA: Allow some configuration, which is shared across users. 4 | 5 | /.idea/* 6 | !.idea/runConfigurations 7 | !.idea/runConfigurations/* 8 | !.idea/vcs.xml 9 | !.idea/dictionaries 10 | !.idea/dictionaries/* 11 | !.idea/inspectionProfiles/* 12 | !.idea/codeStyles 13 | !.idea/codeStyles/* 14 | *.iml 15 | 16 | # Java/Kotlin/Android 17 | 18 | /.gradle 19 | /build 20 | /out 21 | 22 | # JavaScript/Node.JS 23 | 24 | /node_modules 25 | 26 | #### project specific ignores below 27 | 28 | /pubspec_overrides.yaml 29 | 30 | -------------------------------------------------------------------------------- /packages/openapi_code_builder/testapi_array.openapi.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.0 2 | info: 3 | version: 0.1.0 4 | title: Example Api 5 | x-dart-name: TestApi 6 | 7 | paths: 8 | /hello: 9 | get: 10 | summary: Say Hello World 11 | responses: 12 | '200': 13 | description: OK 14 | content: 15 | application/json: 16 | schema: 17 | type: array 18 | items: 19 | $ref: '#/components/schemas/HelloResponse' 20 | components: 21 | schemas: 22 | HelloResponse: 23 | properties: 24 | message: 25 | type: string 26 | description: 'The Hello World greeting ;-)' 27 | -------------------------------------------------------------------------------- /packages/openapi_base/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | # Defines a default set of lint rules enforced for 2 | # projects at Google. For details and rationale, 3 | # see https://github.com/dart-lang/pedantic#enabled-lints. 4 | include: package:lints/recommended.yaml 5 | 6 | analyzer: 7 | errors: 8 | # treat missing required parameters as a warning (not a hint) 9 | missing_required_param: warning 10 | # treat missing returns as a warning (not a hint) 11 | missing_return: warning 12 | # allow having TODOs in the code 13 | todo: ignore 14 | language: 15 | strict-casts: true 16 | strict-raw-types: true 17 | 18 | linter: 19 | rules: 20 | unawaited_futures: true 21 | require_trailing_commas: true 22 | -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/ios/.gitignore: -------------------------------------------------------------------------------- 1 | *.mode1v3 2 | *.mode2v3 3 | *.moved-aside 4 | *.pbxuser 5 | *.perspectivev3 6 | **/*sync/ 7 | .sconsign.dblite 8 | .tags* 9 | **/.vagrant/ 10 | **/DerivedData/ 11 | Icon? 12 | **/Pods/ 13 | **/.symlinks/ 14 | profile 15 | xcuserdata 16 | **/.generated/ 17 | Flutter/App.framework 18 | Flutter/Flutter.framework 19 | Flutter/Flutter.podspec 20 | Flutter/Generated.xcconfig 21 | Flutter/app.flx 22 | Flutter/app.zip 23 | Flutter/flutter_assets/ 24 | Flutter/flutter_export_environment.sh 25 | ServiceDefinitions.json 26 | Runner/GeneratedPluginRegistrant.* 27 | 28 | # Exceptions to above rules. 29 | !default.mode1v3 30 | !default.mode2v3 31 | !default.pbxuser 32 | !default.perspectivev3 33 | -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/android/settings.gradle: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Flutter Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | include ':app' 6 | 7 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties") 8 | def properties = new Properties() 9 | 10 | assert localPropertiesFile.exists() 11 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } 12 | 13 | def flutterSdkPath = properties.getProperty("flutter.sdk") 14 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 15 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" 16 | -------------------------------------------------------------------------------- /packages/openapi_code_builder/lib/openapi_code_builder.dart: -------------------------------------------------------------------------------- 1 | import 'package:build/build.dart'; 2 | import 'package:openapi_code_builder/src/openapi_code_builder.dart'; 3 | 4 | export 'package:openapi_code_builder/src/openapi_code_builder.dart' 5 | show OpenApiLibraryGenerator, OpenApiCodeBuilderUtils; 6 | 7 | Builder openapiCodeBuilder(BuilderOptions options) { 8 | return OpenApiCodeBuilder( 9 | orderDirectives: true, 10 | useNullSafetySyntax: true, 11 | generateProvider: options.config['generateProvider'] as bool? ?? false, 12 | providerNamePrefix: options.config['providerNamePrefix'] as String? ?? '', 13 | ignoreSecuritySchemes: 14 | options.config['ignoreSecuritySchemes'] as bool? ?? false, 15 | ); 16 | } 17 | -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/web/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "openapi_generator_flutter", 3 | "short_name": "openapi_generator_flutter", 4 | "start_url": ".", 5 | "display": "standalone", 6 | "background_color": "#0175C2", 7 | "theme_color": "#0175C2", 8 | "description": "A new Flutter project.", 9 | "orientation": "portrait-primary", 10 | "prefer_related_applications": false, 11 | "icons": [ 12 | { 13 | "src": "icons/Icon-192.png", 14 | "sizes": "192x192", 15 | "type": "image/png" 16 | }, 17 | { 18 | "src": "icons/Icon-512.png", 19 | "sizes": "512x512", 20 | "type": "image/png" 21 | } 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /packages/openapi_code_builder/.idea/runConfigurations/build_runner.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 13 | -------------------------------------------------------------------------------- /packages/openapi_code_builder/example/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: openapi_code_builder_example 2 | description: Example use of openapi code builder. 3 | # version: 1.0.0 4 | # homepage: https://www.example.com 5 | 6 | environment: 7 | sdk: '>=3.8.0 <4.0.0' 8 | 9 | dependencies: 10 | freezed_annotation: ^3.1.0 11 | json_annotation: ^4.8.1 12 | logging: ^1.0.0 13 | logging_appenders: ^1.0.0 14 | openapi_base: 15 | path: ../../openapi_base 16 | 17 | dev_dependencies: 18 | openapi_code_builder: 19 | path: ../ 20 | json_serializable: ^6.9.0 21 | freezed: ^3.2.0 22 | build_runner: ^2.4.8 23 | lints: ^6.0.0 24 | 25 | dependency_overrides: 26 | openapi_base: 27 | path: ../../openapi_base 28 | open_api_forked: 29 | path: ../../../deps/open-api-dart 30 | -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.7.0' 3 | repositories { 4 | google() 5 | mavenCentral() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:7.2.1' 10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 11 | } 12 | } 13 | 14 | allprojects { 15 | repositories { 16 | google() 17 | mavenCentral() 18 | } 19 | } 20 | 21 | rootProject.buildDir = '../build' 22 | subprojects { 23 | project.buildDir = "${rootProject.buildDir}/${project.name}" 24 | } 25 | subprojects { 26 | project.evaluationDependsOn(':app') 27 | } 28 | 29 | task clean(type: Delete) { 30 | delete rootProject.buildDir 31 | } 32 | -------------------------------------------------------------------------------- /packages/openapi_base/lib/src/server/openapi_shelf_noop_server.dart: -------------------------------------------------------------------------------- 1 | import 'package:openapi_base/src/openapi_base.dart'; 2 | import 'package:openapi_base/src/server/openapi_server_base.dart'; 3 | import 'package:openapi_base/src/util/internal_utils.dart'; 4 | import 'package:shelf/shelf.dart' as shelf; 5 | 6 | /// Noop server used if no dart:io is available. 7 | class OpenApiShelfServer extends OpenApiServerBase { 8 | factory OpenApiShelfServer( 9 | OpenApiServerRouterBase router, { 10 | shelf.Pipeline Function(shelf.Pipeline pipeline) customizePipeline = 11 | identity, 12 | }) => 13 | throw StateError('Unsupported $router $customizePipeline'); 14 | 15 | @override 16 | dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); 17 | } 18 | -------------------------------------------------------------------------------- /packages/openapi_base/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: openapi_base 2 | description: Open API base implementation for client/server to be used with openapi_code_builder. 3 | version: 2.0.0 4 | homepage: https://github.com/hpoul/openapi_dart/tree/master/packages/openapi_base 5 | 6 | environment: 7 | sdk: '>=3.3.0 <4.0.0' 8 | 9 | dependencies: 10 | # path: ^1.7.0 11 | collection: ">=1.16.0 <2.0.0" 12 | meta: ">=1.3.0 <2.0.0" 13 | open_api_forked: ">=3.0.0 <4.0.0" 14 | uri: ^1.0.0 15 | logging: ">=1.0.0 <2.0.0" 16 | logging_appenders: ">=1.0.0 <2.0.0" 17 | 18 | uuid: ">=4.0.0 <5.0.0" 19 | json_annotation: ">=4.0.0 <6.0.0" 20 | chunked_stream: ">=1.4.1 <2.0.0" 21 | 22 | # server 23 | shelf: ">=1.0.0 <2.0.0" 24 | # shelf_cookie: ">=1.1.1 <2.0.0" 25 | 26 | # for the client: 27 | http: ">=0.13.0 <2.0.0" 28 | http_parser: ">=4.0.0 <5.0.0" 29 | 30 | dev_dependencies: 31 | lints: ^4.0.0 32 | -------------------------------------------------------------------------------- /.github/workflows/flutter-gh-pages.yaml: -------------------------------------------------------------------------------- 1 | name: github pages 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | deploy: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v3 13 | 14 | - name: Setup Flutter 15 | uses: subosito/flutter-action@v2 16 | with: 17 | channel: 'stable' 18 | 19 | - name: Install 20 | run: | 21 | flutter config --enable-web 22 | cd packages/openapi_generator_flutter && flutter pub get 23 | - name: Build 24 | run: cd packages/openapi_generator_flutter && flutter build web --base-href /openapi_dart/ 25 | 26 | - name: Deploy 27 | uses: peaceiris/actions-gh-pages@v3 28 | with: 29 | github_token: ${{ secrets.GITHUB_TOKEN }} 30 | publish_dir: ./packages/openapi_generator_flutter/build/web 31 | allow_empty_commit: true 32 | 33 | -------------------------------------------------------------------------------- /packages/openapi_code_builder/example/bin/example_client.dart: -------------------------------------------------------------------------------- 1 | import 'package:logging/logging.dart'; 2 | import 'package:logging_appenders/logging_appenders.dart'; 3 | import 'package:openapi_base/openapi_base.dart'; 4 | import 'package:openapi_code_builder_example/src/api/testapi.openapi.dart'; 5 | 6 | final _logger = Logger('example_server'); 7 | 8 | Future main() async { 9 | PrintAppender.setupLogging(); 10 | _logger.fine('Starting Client ...'); 11 | final requestSender = HttpRequestSender(); 12 | final client = TestApiClient( 13 | // Uri.parse('https://virtserver.swaggerhub.com/hpoul/Testapi/1.0.0'), 14 | Uri.parse('http://localhost:8080'), 15 | requestSender); 16 | final blubb = await client.helloNameGet(name: 'Blubb'); 17 | blubb.map( 18 | on200: (response) => _logger.info('Success: ${response.body.message}'), 19 | ); 20 | _logger.info('Response: $blubb'); 21 | requestSender.dispose(); 22 | } 23 | -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | **/ios/Flutter/.last_build_id 26 | .dart_tool/ 27 | .flutter-plugins 28 | .flutter-plugins-dependencies 29 | .packages 30 | .pub-cache/ 31 | .pub/ 32 | /build/ 33 | 34 | # Web related 35 | lib/generated_plugin_registrant.dart 36 | 37 | # Symbolication related 38 | app.*.symbols 39 | 40 | # Obfuscation related 41 | app.*.map.json 42 | 43 | # Exceptions to above rules. 44 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 45 | -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 8.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /packages/openapi_code_builder/.idea/runConfigurations/build_runner_build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 17 | -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled. 5 | 6 | version: 7 | revision: 676cefaaff197f27424942307668886253e1ec35 8 | channel: stable 9 | 10 | project_type: app 11 | 12 | # Tracks metadata for the flutter migrate command 13 | migration: 14 | platforms: 15 | - platform: root 16 | create_revision: 676cefaaff197f27424942307668886253e1ec35 17 | base_revision: 676cefaaff197f27424942307668886253e1ec35 18 | - platform: web 19 | create_revision: 676cefaaff197f27424942307668886253e1ec35 20 | base_revision: 676cefaaff197f27424942307668886253e1ec35 21 | 22 | # User provided section 23 | 24 | # List of Local paths (relative to this file) that should be 25 | # ignored by the migrate tool. 26 | # 27 | # Files that are not part of the templates will be ignored by default. 28 | unmanaged_files: 29 | - 'lib/main.dart' 30 | - 'ios/Runner.xcodeproj/project.pbxproj' 31 | -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /packages/openapi_code_builder/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: openapi_code_builder 2 | description: Generate Dtos, client and server scaffolds for openapi specs. 3 | version: 1.8.0 4 | homepage: https://github.com/hpoul/openapi_dart/tree/master/packages/openapi_code_builder 5 | 6 | environment: 7 | sdk: '>=3.8.0 <4.0.0' 8 | 9 | dependencies: 10 | logging: ">=1.0.1 <2.0.0" 11 | logging_appenders: ^1.1.0 12 | meta: ">=1.5.0 <2.0.0" 13 | openapi_base: ">=2.0.0 <3.0.0" 14 | path: ">=1.8.0 <2.0.0" 15 | pub_semver: ">=2.0.0 <3.0.0" 16 | dart_style: ">=2.0.1 <4.0.0" 17 | code_builder: ">=4.0.0 <5.0.0" 18 | build: ">=2.0.2 <5.0.0" 19 | source_gen: ">=1.0.2 <5.0.0" 20 | open_api_forked: ^3.0.0+6 21 | yaml: ">=3.1.0 <4.0.0" 22 | json_annotation: ">=4.0.1 <6.0.0" 23 | recase: ^4.1.0 24 | quiver: ">=3.0.1 <4.0.0" 25 | built_collection: ">=5.1.0 <6.0.0" 26 | collection: ">=1.15.0 <2.0.0" 27 | 28 | dev_dependencies: 29 | lints: ^6.0.0 30 | 31 | #dependency_overrides: 32 | # openapi_base: 33 | # path: ../openapi_base 34 | # open_api_forked: 35 | # path: ../../deps/open-api-dart 36 | # codable_forked: 37 | # path: ../../deps/dart-codable 38 | -------------------------------------------------------------------------------- /packages/openapi_base/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Herbert Poul 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/openapi_code_builder/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Herbert Poul 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/openapi_code_builder/bin/openapi_code_builder_cli.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:logging_appenders/logging_appenders.dart'; 4 | import 'package:openapi_code_builder/openapi_code_builder.dart'; 5 | import 'package:path/path.dart' as path; 6 | import 'package:recase/recase.dart'; 7 | 8 | Future main(List args) async { 9 | if (args.isEmpty) { 10 | print('Usage: ${Platform.executable} '); 11 | exit(1); 12 | } 13 | PrintAppender.setupLogging(); 14 | final fileName = args[0]; 15 | final file = File(fileName); 16 | final source = await file.readAsString(); 17 | final api = OpenApiCodeBuilderUtils.loadApiFromYaml(source); 18 | final baseName = path.basenameWithoutExtension(fileName).pascalCase; 19 | 20 | final library = OpenApiLibraryGenerator( 21 | api, 22 | baseName: baseName, 23 | partFileName: '${path.basenameWithoutExtension(fileName)}.g.dart', 24 | useNullSafetySyntax: true, 25 | ignoreSecuritySchemes: true, 26 | ).generate(); 27 | final libraryOutput = OpenApiCodeBuilderUtils.formatLibrary( 28 | library, 29 | orderDirectives: true, 30 | useNullSafetySyntax: true, 31 | ); 32 | print(libraryOutput); 33 | } 34 | -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/test/widget_test.dart: -------------------------------------------------------------------------------- 1 | // This is a basic Flutter widget test. 2 | // 3 | // To perform an interaction with a widget in your test, use the WidgetTester 4 | // utility that Flutter provides. For example, you can send tap and scroll 5 | // gestures. You can also use WidgetTester to find child widgets in the widget 6 | // tree, read text, and verify that the values of widget properties are correct. 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'package:flutter_test/flutter_test.dart'; 10 | 11 | import 'package:openapi_generator_flutter/main.dart'; 12 | 13 | void main() { 14 | testWidgets('Counter increments smoke test', (WidgetTester tester) async { 15 | // Build our app and trigger a frame. 16 | await tester.pumpWidget(const MyApp()); 17 | 18 | // Verify that our counter starts at 0. 19 | expect(find.text('0'), findsOneWidget); 20 | expect(find.text('1'), findsNothing); 21 | 22 | // Tap the '+' icon and trigger a frame. 23 | await tester.tap(find.byIcon(Icons.add)); 24 | await tester.pump(); 25 | 26 | // Verify that our counter has incremented. 27 | expect(find.text('0'), findsNothing); 28 | expect(find.text('1'), findsOneWidget); 29 | }); 30 | } 31 | -------------------------------------------------------------------------------- /packages/openapi_base/lib/src/util/shelf_cookie/shelf_cookie.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | import 'dart:io'; 3 | 4 | import 'package:shelf/shelf.dart' as shelf; 5 | 6 | import 'cookie_parser.dart'; 7 | 8 | /// Creates a Shelf [Middleware] to parse cookies. 9 | /// 10 | /// Adds a [CookieParser] instance to `request.context['cookies']`, 11 | /// with convenience methods to manipulate cookies in request handlers. 12 | /// 13 | /// Adds a `Set-Cookie` HTTP header to the response with all cookies. 14 | shelf.Middleware cookieParser() { 15 | return (shelf.Handler innerHandler) { 16 | return (shelf.Request request) { 17 | final cookies = CookieParser.fromHeader(request.headers); 18 | return Future.sync(() { 19 | return innerHandler( 20 | request.change(context: {'cookies': cookies}), 21 | ); 22 | }).then( 23 | (shelf.Response response) { 24 | if (cookies.isEmpty) { 25 | return response; 26 | } 27 | return response.change( 28 | headers: {HttpHeaders.setCookieHeader: cookies.toString()}, 29 | ); 30 | }, 31 | onError: (Object error, StackTrace stackTrace) { 32 | throw error; 33 | }, 34 | ); 35 | }; 36 | }; 37 | } 38 | -------------------------------------------------------------------------------- /packages/openapi_code_builder/lib/src/custom_allocator.dart: -------------------------------------------------------------------------------- 1 | import 'package:code_builder/code_builder.dart'; 2 | 3 | /// The same as `Allocator.simplePrefixing` but will also not prefix 4 | /// `openapi_base`. 5 | class CustomAllocator implements Allocator { 6 | static const _doNotPrefix = [ 7 | 'dart:core', 8 | 'package:openapi_base/openapi_base.dart', 9 | // https://github.com/google/json_serializable.dart/issues/1115 10 | 'package:json_annotation/json_annotation.dart', 11 | 'package:freezed_annotation/freezed_annotation.dart', 12 | ]; 13 | 14 | final _imports = {}; 15 | var _keys = 1; 16 | 17 | @override 18 | String allocate(Reference reference) { 19 | final symbol = reference.symbol; 20 | final url = reference.url; 21 | if (symbol == null) { 22 | throw ArgumentError.notNull('reference.symbol'); 23 | } 24 | if (url == null || _doNotPrefix.contains(url)) { 25 | return symbol; 26 | } 27 | return '_i${_imports.putIfAbsent(url, _nextKey)}.$symbol'; 28 | } 29 | 30 | int _nextKey() => _keys++; 31 | 32 | @override 33 | Iterable get imports { 34 | return _imports.keys 35 | .map((u) => Directive.import(u, as: '_i${_imports[u]}')) 36 | .followedBy( 37 | _doNotPrefix 38 | .where((element) => element.startsWith('package:')) 39 | .map((e) => Directive.import(e)), 40 | ); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /packages/openapi_base/lib/src/server/stoppable_process.dart: -------------------------------------------------------------------------------- 1 | // https://github.com/stablekernel/aqueduct/blob/master/aqueduct/lib/src/cli/running_process.dart 2 | 3 | import 'dart:async'; 4 | import 'dart:io'; 5 | 6 | import 'package:openapi_base/src/server/openapi_server_base.dart'; 7 | 8 | typedef _StopProcess = Future Function(String reason); 9 | 10 | class StoppableProcess extends StoppableProcessBase { 11 | StoppableProcess(Future Function(String reason) onStop) 12 | : _stop = onStop { 13 | final l1 = ProcessSignal.sigint.watch().listen((_) { 14 | stop(0, reason: 'Process interrupted.'); 15 | }); 16 | _listeners.add(l1); 17 | 18 | if (!Platform.isWindows) { 19 | final l2 = ProcessSignal.sigterm.watch().listen((_) { 20 | stop(0, reason: 'Process terminated by OS.'); 21 | }); 22 | _listeners.add(l2); 23 | } 24 | } 25 | 26 | @override 27 | Future get exitCode => _completer.future; 28 | 29 | final List> _listeners = []; 30 | 31 | final _StopProcess _stop; 32 | final Completer _completer = Completer(); 33 | 34 | @override 35 | Future stop(int exitCode, {String? reason}) async { 36 | if (_completer.isCompleted) { 37 | return; 38 | } 39 | 40 | for (final sub in _listeners) { 41 | await sub.cancel(); 42 | } 43 | await _stop(reason ?? 'Terminated normally.'); 44 | _completer.complete(exitCode); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /packages/openapi_base/lib/src/openapi_content_type.dart: -------------------------------------------------------------------------------- 1 | import 'package:http_parser/http_parser.dart'; 2 | 3 | /// Represents the content type header describing content encoding for 4 | /// request and responses. 5 | class OpenApiContentType { 6 | const OpenApiContentType._(this.contentType, [this.mediaType]); 7 | 8 | /// Parses the value as returned by [toString] 9 | factory OpenApiContentType.parse(String value) { 10 | final mediaType = MediaType.parse(value); 11 | return OpenApiContentType._(value, mediaType); 12 | } 13 | 14 | final MediaType? mediaType; 15 | 16 | static const json = OpenApiContentType._('application/json'); 17 | static const html = OpenApiContentType._('text/html'); 18 | static const textPlain = OpenApiContentType._('text/plain'); 19 | static const octetStream = OpenApiContentType._('application/octet-stream'); 20 | static const urlencoded = 21 | OpenApiContentType._('application/x-www-form-urlencoded'); 22 | 23 | final String contentType; 24 | 25 | bool get isString => contentType.startsWith('text/'); 26 | 27 | bool get isJson => contentType.startsWith(json.contentType); 28 | 29 | static const allKnown = [json, html, urlencoded]; 30 | 31 | String? get charset => mediaType?.parameters['charset']; 32 | 33 | /// Reverse of [parse] 34 | @override 35 | String toString() { 36 | return contentType; 37 | } 38 | 39 | bool matches(OpenApiContentType contentType) { 40 | // TODO we should probably support wildcards, ignore encodings, etc. 41 | return this.contentType == contentType.contentType; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | # This file configures the analyzer, which statically analyzes Dart code to 2 | # check for errors, warnings, and lints. 3 | # 4 | # The issues identified by the analyzer are surfaced in the UI of Dart-enabled 5 | # IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be 6 | # invoked from the command line by running `flutter analyze`. 7 | 8 | # The following line activates a set of recommended lints for Flutter apps, 9 | # packages, and plugins designed to encourage good coding practices. 10 | include: package:flutter_lints/flutter.yaml 11 | 12 | linter: 13 | # The lint rules applied to this project can be customized in the 14 | # section below to disable rules from the `package:flutter_lints/flutter.yaml` 15 | # included above or to enable additional rules. A list of all available lints 16 | # and their documentation is published at 17 | # https://dart-lang.github.io/linter/lints/index.html. 18 | # 19 | # Instead of disabling a lint rule for the entire project in the 20 | # section below, it can also be suppressed for a single line of code 21 | # or a specific dart file by using the `// ignore: name_of_lint` and 22 | # `// ignore_for_file: name_of_lint` syntax on the line or in the file 23 | # producing the lint. 24 | rules: 25 | # avoid_print: false # Uncomment to disable the `avoid_print` rule 26 | # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule 27 | 28 | # Additional information about this file can be found at 29 | # https://dart.dev/guides/language/analysis-options 30 | -------------------------------------------------------------------------------- /packages/openapi_base/lib/src/util/uuid.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | import 'package:uuid/data.dart'; 3 | import 'package:uuid/rng.dart'; 4 | import 'package:uuid/uuid.dart' as uuid; 5 | 6 | @ApiUuidJsonConverter() 7 | class ApiUuid { 8 | ApiUuid._(this._uuid) : assert(_isUuid(_uuid)); 9 | 10 | ApiUuid.secure() : this._(_secureUuidGenerator.v4()); 11 | 12 | /// Parse the given uuid. This is the reverse of [encodeToString]. 13 | ApiUuid.parse(String uuid) : this._(uuid); 14 | 15 | static final _secureUuidGenerator = 16 | uuid.Uuid(goptions: GlobalOptions(CryptoRNG())); 17 | static final _validate = RegExp( 18 | r'^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$', 19 | caseSensitive: false, 20 | ); 21 | 22 | static bool _isUuid(String uuid) { 23 | return _validate.hasMatch(uuid); 24 | } 25 | 26 | final String _uuid; 27 | 28 | /// Encodes UUID into a [String]. Opposite of [ApiUuid.parse]. 29 | String encodeToString() => _uuid; 30 | 31 | /// String representation for debugging. 32 | /// Use [encodeToString] to use for transmission. 33 | @override 34 | String toString() => _uuid; 35 | 36 | @override 37 | bool operator ==(Object other) => other is ApiUuid && _uuid == other._uuid; 38 | 39 | @override 40 | int get hashCode => _uuid.hashCode; 41 | } 42 | 43 | class ApiUuidJsonConverter implements JsonConverter { 44 | const ApiUuidJsonConverter(); 45 | 46 | @override 47 | ApiUuid fromJson(String json) => ApiUuid.parse(json); 48 | 49 | @override 50 | String toJson(ApiUuid object) => object.encodeToString(); 51 | } 52 | -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | openapi_generator_flutter 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | $(FLUTTER_BUILD_NAME) 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | UIInterfaceOrientationLandscapeLeft 33 | UIInterfaceOrientationLandscapeRight 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UIViewControllerBasedStatusBarAppearance 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply plugin: 'kotlin-android' 26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 27 | 28 | android { 29 | compileSdkVersion 31 30 | 31 | sourceSets { 32 | main.java.srcDirs += 'src/main/kotlin' 33 | } 34 | 35 | 36 | defaultConfig { 37 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 38 | applicationId "com.example.openapi_generator_flutter" 39 | minSdkVersion 16 40 | targetSdkVersion 31 41 | versionCode flutterVersionCode.toInteger() 42 | versionName flutterVersionName 43 | } 44 | 45 | buildTypes { 46 | release { 47 | // TODO: Add your own signing config for the release build. 48 | // Signing with the debug keys for now, so `flutter run --release` works. 49 | signingConfig signingConfigs.debug 50 | } 51 | } 52 | lint { 53 | disable 'InvalidPackage' 54 | } 55 | } 56 | 57 | flutter { 58 | source '../..' 59 | } 60 | 61 | dependencies { 62 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 63 | } 64 | -------------------------------------------------------------------------------- /packages/openapi_code_builder/example/bin/example_server.dart: -------------------------------------------------------------------------------- 1 | import 'package:logging/logging.dart'; 2 | import 'package:logging_appenders/logging_appenders.dart'; 3 | import 'package:openapi_base/openapi_base.dart'; 4 | import 'package:openapi_code_builder_example/src/api/testapi.openapi.dart'; 5 | 6 | final _logger = Logger('example_server'); 7 | 8 | Future main() async { 9 | PrintAppender.setupLogging(); 10 | _logger.fine('Starting Server ...'); 11 | final server = OpenApiShelfServer( 12 | TestApiRouter(ApiEndpointProvider.static(TestApiImpl())), 13 | ); 14 | final process = await server.startServer(); 15 | _logger.fine('startServer finished.'); 16 | final exitCode = await process.exitCode; 17 | _logger.fine('exitCode from process: $exitCode'); 18 | } 19 | 20 | class TestApiImpl extends TestApi { 21 | @override 22 | Future helloNamePut(HelloRequest body, 23 | {required String name}) async { 24 | return HelloNamePutResponse.response200( 25 | HelloResponse(message: 'Hello ${body.salutation} $name')); 26 | } 27 | 28 | @override 29 | Future helloNameGet( 30 | {required String name, String? salutation}) async { 31 | _logger.info('Saying hi to $name (salutation: $salutation)'); 32 | return HelloNameGetResponse.response200( 33 | HelloResponse(message: 'Hello ${salutation ?? 'Dear'} $name')); 34 | } 35 | 36 | @override 37 | Future userRegisterPost(RegisterRequest body) { 38 | // TODO: implement userRegisterPost 39 | throw UnimplementedError(); 40 | } 41 | 42 | @override 43 | Future helloNameHtmlGet( 44 | {required String name}) async { 45 | // language=html 46 | return HelloNameHtmlGetResponse.response200(''' 47 | Hello World 48 | 49 |

Hello $name!

50 |

How are you? 51 | '''); 52 | } 53 | 54 | @override 55 | Future uuidExampleMessageIdGet( 56 | {required ApiUuid messageId}) async { 57 | return UuidExampleMessageIdGetResponse.response200( 58 | UuidExampleMessageIdGetResponseBody200(id: messageId)); 59 | } 60 | 61 | @override 62 | Future helloIntegerPut(int body) async { 63 | return HelloIntegerPutResponse.response200(); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /packages/openapi_base/lib/src/openapi_exception.dart: -------------------------------------------------------------------------------- 1 | import 'package:openapi_base/openapi_base.dart'; 2 | 3 | /// Base class for exceptions which can be thrown by endpoint implementations 4 | /// with special handling in the server implementations 5 | /// (e.g. [OpenApiShelfServer]). 6 | /// 7 | /// This allows custom status code responses without explicit definition 8 | /// in the OpenApi yaml file. 9 | abstract class OpenApiResponseException implements Exception { 10 | int get status; 11 | 12 | String get message; 13 | 14 | @override 15 | String toString() { 16 | return '$runtimeType{status=$status,message=$message}'; 17 | } 18 | } 19 | 20 | class UnexpectedResponseException extends OpenApiResponseException { 21 | UnexpectedResponseException({ 22 | required this.status, 23 | String? message, 24 | required this.request, 25 | required this.response, 26 | }) : message = message ?? 27 | 'Unexpected response from server for ${request.operation} ${request.path} (${response.status})'; 28 | 29 | @override 30 | final int status; 31 | @override 32 | final String message; 33 | final OpenApiClientResponse response; 34 | final OpenApiClientRequest request; 35 | } 36 | 37 | /// Server exception which can be thrown by implementations of 38 | /// the server endpoint to indicate a 401 response status. 39 | class UnauthorizedException extends OpenApiResponseException 40 | implements Exception { 41 | UnauthorizedException(this.message); 42 | 43 | @override 44 | int get status => OpenApiHttpStatus.unauthorized; 45 | 46 | @override 47 | final String message; 48 | } 49 | 50 | class NotFoundException extends OpenApiResponseException { 51 | NotFoundException(this.message); 52 | 53 | @override 54 | int get status => OpenApiHttpStatus.notFound; 55 | 56 | @override 57 | final String message; 58 | } 59 | 60 | class ConflictException extends OpenApiResponseException { 61 | ConflictException(this.message); 62 | 63 | @override 64 | int get status => OpenApiHttpStatus.conflict; 65 | 66 | @override 67 | final String message; 68 | } 69 | 70 | class MissingParameterException extends OpenApiResponseException { 71 | MissingParameterException(this.parameterName); 72 | 73 | @override 74 | int get status => OpenApiHttpStatus.badRequest; 75 | 76 | final String parameterName; 77 | 78 | @override 79 | String get message => 'Parameter "$parameterName" is required.'; 80 | } 81 | -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /packages/openapi_base/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 2.0.0 2 | 3 | * Use UTF-8 encoding by default for json responses. 4 | * Support for dynamic request bodys (instead of just `Map`). 5 | 6 | ## 1.3.2 7 | 8 | * Allow encoding optional parameters. 9 | 10 | ## 1.3.1 11 | 12 | * bump UUID version constraint to support `4.x` 13 | 14 | ## 1.3.0 15 | 16 | * `ResponseMap` now has a return type. 17 | 18 | ## 1.1.0+3 19 | 20 | * Update http version constraints. 21 | * Fix dart analysis warnings. 22 | 23 | ## 1.1.0+2 24 | 25 | * Fix optional query parameter #5 26 | * Extend startServer method to accept all io.serve parameter #6 (thanks @Bonnyfication) 27 | 28 | ## 1.1.0+1 29 | 30 | * Fix json conversion. 31 | 32 | ## 1.1.0 33 | 34 | * Require json responses to return dynamic, to support array response objects. 35 | 36 | ## 1.0.3+2 37 | 38 | * Improve "unexpected response" client exception. 39 | 40 | ## 1.0.3+1 41 | 42 | * Support Stream clients. 43 | 44 | ## 1.0.3 45 | 46 | * Support for `number` type. 47 | 48 | ## 1.0.2+3 49 | 50 | * Upgrade dependencies, fix analysis warnings. 51 | ======= 52 | 53 | ## 1.0.2+2 54 | 55 | * Handle missing parameters as exception (status 400), not an error (status 500). 56 | * Allow handling of exceptions in middleware. 57 | 58 | ## 1.0.2+1 59 | 60 | * Fix including headers for unknown/error responses. 61 | 62 | ## 1.0.2 63 | 64 | * Allow customizing of the shelf pipeline with additional middleware. 65 | 66 | ## 1.0.1+4 67 | 68 | * introduced `OpenApiHttpStatus` constants. 69 | * Fix sending of binary request data. 70 | * Fix passing on headers to callers. 71 | 72 | ## 1.0.1 73 | 74 | * Support for binary request bodys 75 | 76 | ## 1.0.0 77 | 78 | * Added conflict exception. 79 | 80 | ## 0.2.0+2 81 | 82 | * Fix contentType nullability. 83 | 84 | ## 0.2.0 85 | 86 | * Null safety migration 87 | 88 | ## 0.1.5+3 89 | 90 | * ApiUuid: Implement operator== and hashCode(). 91 | 92 | ## 0.1.5+2 93 | 94 | * Allow customizing of http clients, to override user-agent. 95 | 96 | ## 0.1.5+1 97 | 98 | * Fix ApiUuid parsing/encoding in url parameters. 99 | 100 | ## 0.1.5 101 | 102 | * Support for binary responses. 103 | 104 | ## 0.1.4 105 | 106 | * Add support for `uuid` format. 107 | 108 | ## 0.1.3+3 109 | 110 | * Allow usage without dart:io, server implementation 111 | will not be available. 112 | 113 | ## 0.1.2 114 | 115 | * Support for optional query parameters 116 | * Match the whole path on the server (not prefix matching) 117 | * Improve body types, etc. 118 | 119 | ## 0.1.1 120 | 121 | * More documentation, various extension methods, etc. 122 | 123 | ## 0.1.0 124 | 125 | Initial release 126 | -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 8 | 11 | 19 | 23 | 27 | 32 | 36 | 37 | 38 | 39 | 40 | 41 | 43 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /packages/openapi_code_builder/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 1.8.0 2 | 3 | * Enum constant values now enforce snake case. (possible incompatibility) 4 | 5 | ## 1.7.0+2 6 | 7 | * Use latest language version for formatter. 8 | 9 | ## 1.7.0+1 10 | 11 | * Make `@freezed` classes `sealed`. 12 | 13 | ## 1.7.0 14 | 15 | * Dart 3.8 16 | * Upgrade `source_gen` (3.x), `build` (3.x), etc. 17 | * Don't break on multi-line descriptions/docs. 18 | 19 | ## 1.6.0+2 20 | 21 | * Add ignore `annotate_overrides`. 22 | 23 | ## 1.6.0+1 24 | 25 | * Support for restricted `additionalProperties` 26 | * Support for json responses of type String (instead of Object/Array). 27 | 28 | ## 1.5.0 29 | 30 | * Support for recursive schemas. (A class referencing itself). 31 | 32 | ## 1.4.0 33 | 34 | * Make constructors for generated classes `const`. 35 | 36 | ## 1.3.3 37 | 38 | * Support for `application/json` requests with primitive body types. 39 | 40 | ## 1.3.2+1 41 | 42 | * Upgrade `openapi_base` dependency. 43 | 44 | ## 1.3.2 45 | 46 | * Support `additionalProperties` for inherited models/schemas. 47 | 48 | ## 1.3.1 49 | 50 | * use import `riverpod/riverpod.dart` instead of `hooks_riverpod` 51 | 52 | ## 1.3.0 53 | 54 | * Update SDK Constraint to `>= 3.2.0 <4.0.0` 55 | * add `onElse` to `map` functions and allow a return value. 56 | * Make base Response classes `sealed`. 57 | 58 | ## 1.2.0 59 | 60 | * Support `DateTime` format for parameters. 61 | 62 | ## 1.1.4+4 63 | 64 | * Add option to ignore security schemes. 65 | 66 | ## 1.1.4+1 67 | 68 | * Client: generate riverpod `.autoDispose` providers. 69 | 70 | ## 1.1.4 71 | 72 | * Client Only: Add support for array response types. 73 | 74 | ## 1.1.3+2 75 | 76 | * Don't include optional non-nullable json properties when null. 77 | 78 | ## 1.1.3+1 79 | 80 | * support encoding of optional uuid parameters. 81 | * Added option to generate `StreamProvider` for integration with riverpod. (TODO: add documentation) 82 | 83 | ## 1.1.2+1 84 | 85 | * Fix optional enum conversion. 86 | 87 | ## 1.1.2 88 | 89 | * Support for enums outside of arrays 90 | * Support for number type. 91 | 92 | ## 1.1.1+1 93 | 94 | * Upgrade dependencies, fix analysis warnings. 95 | 96 | ## 1.1.1 97 | 98 | * Improve handling of enum components. 99 | 100 | ## 1.1.0 101 | 102 | * Migrate to null safety. 103 | 104 | ## 1.0.1 105 | 106 | * Support for binary request body. 107 | * Updated dependencies. 108 | 109 | ## 1.0.0 110 | 111 | * Cleanup post-nnbd: Removed many forced null unwraps. 112 | 113 | ## 0.1.4+2 114 | 115 | * Upgrade dependencies, fixed warnings. 116 | 117 | ## 0.1.4+1 118 | 119 | * Add support for `uuid` format. 120 | 121 | ## 0.1.2 122 | 123 | - Support for freeform `additionalProperties` 124 | 125 | ## 0.1.1 126 | 127 | - Better URL handling 128 | - Improve response object. 129 | 130 | ## 0.1.0 131 | 132 | - Initial version 133 | 134 | -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: openapi_generator_flutter 2 | description: An easy web UI to try out openapi_code_builder. 3 | 4 | # The following line prevents the package from being accidentally published to 5 | # pub.dev using `pub publish`. This is preferred for private packages. 6 | publish_to: 'none' # Remove this line if you wish to publish to pub.dev 7 | 8 | # The following defines the version and build number for your application. 9 | # A version number is three numbers separated by dots, like 1.2.43 10 | # followed by an optional build number separated by a +. 11 | # Both the version and the builder number may be overridden in flutter 12 | # build by specifying --build-name and --build-number, respectively. 13 | # In Android, build-name is used as versionName while build-number used as versionCode. 14 | # Read more about Android versioning at https://developer.android.com/studio/publish/versioning 15 | # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. 16 | # Read more about iOS versioning at 17 | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html 18 | version: 1.0.0+1 19 | 20 | environment: 21 | sdk: '>=3.5.0 <4.0.0' 22 | 23 | dependencies: 24 | flutter: 25 | sdk: flutter 26 | openapi_code_builder: 27 | path: ../openapi_code_builder 28 | flutter_markdown: ^0.7.5 29 | url_launcher: ^6.1.7 30 | google_fonts: ^6.2.1 31 | logging: ^1.1.0 32 | logging_appenders: ^1.0.0 33 | 34 | dev_dependencies: 35 | flutter_test: 36 | sdk: flutter 37 | flutter_lints: ^5.0.0 38 | 39 | dependency_overrides: 40 | openapi_base: 41 | path: ../openapi_base 42 | 43 | # For information on the generic Dart part of this file, see the 44 | # following page: https://dart.dev/tools/pub/pubspec 45 | 46 | # The following section is specific to Flutter. 47 | flutter: 48 | 49 | # The following line ensures that the Material Icons font is 50 | # included with your application, so that you can use the icons in 51 | # the material Icons class. 52 | uses-material-design: true 53 | 54 | assets: 55 | - assets/ 56 | 57 | # An image asset can refer to one or more resolution-specific "variants", see 58 | # https://flutter.dev/assets-and-images/#resolution-aware. 59 | 60 | # For details regarding adding assets from package dependencies, see 61 | # https://flutter.dev/assets-and-images/#from-packages 62 | 63 | # To add custom fonts to your application, add a fonts section here, 64 | # in this "flutter" section. Each entry in this list should have a 65 | # "family" key with the font family name, and a "fonts" key with a 66 | # list giving the asset and other descriptors for the font. For 67 | # example: 68 | # fonts: 69 | # - family: Schyler 70 | # fonts: 71 | # - asset: fonts/Schyler-Regular.ttf 72 | # - asset: fonts/Schyler-Italic.ttf 73 | # style: italic 74 | # - family: Trajan Pro 75 | # fonts: 76 | # - asset: fonts/TrajanPro.ttf 77 | # - asset: fonts/TrajanPro_Bold.ttf 78 | # weight: 700 79 | # 80 | # For details regarding fonts from package dependencies, 81 | # see https://flutter.dev/custom-fonts/#from-packages 82 | -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | # platform :ios, '9.0' 3 | 4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 6 | 7 | project 'Runner', { 8 | 'Debug' => :debug, 9 | 'Profile' => :release, 10 | 'Release' => :release, 11 | } 12 | 13 | def parse_KV_file(file, separator='=') 14 | file_abs_path = File.expand_path(file) 15 | if !File.exists? file_abs_path 16 | return []; 17 | end 18 | generated_key_values = {} 19 | skip_line_start_symbols = ["#", "/"] 20 | File.foreach(file_abs_path) do |line| 21 | next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ } 22 | plugin = line.split(pattern=separator) 23 | if plugin.length == 2 24 | podname = plugin[0].strip() 25 | path = plugin[1].strip() 26 | podpath = File.expand_path("#{path}", file_abs_path) 27 | generated_key_values[podname] = podpath 28 | else 29 | puts "Invalid plugin specification: #{line}" 30 | end 31 | end 32 | generated_key_values 33 | end 34 | 35 | target 'Runner' do 36 | use_frameworks! 37 | use_modular_headers! 38 | 39 | # Flutter Pod 40 | 41 | copied_flutter_dir = File.join(__dir__, 'Flutter') 42 | copied_framework_path = File.join(copied_flutter_dir, 'Flutter.framework') 43 | copied_podspec_path = File.join(copied_flutter_dir, 'Flutter.podspec') 44 | unless File.exist?(copied_framework_path) && File.exist?(copied_podspec_path) 45 | # Copy Flutter.framework and Flutter.podspec to Flutter/ to have something to link against if the xcode backend script has not run yet. 46 | # That script will copy the correct debug/profile/release version of the framework based on the currently selected Xcode configuration. 47 | # CocoaPods will not embed the framework on pod install (before any build phases can generate) if the dylib does not exist. 48 | 49 | generated_xcode_build_settings_path = File.join(copied_flutter_dir, 'Generated.xcconfig') 50 | unless File.exist?(generated_xcode_build_settings_path) 51 | raise "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter pub get is executed first" 52 | end 53 | generated_xcode_build_settings = parse_KV_file(generated_xcode_build_settings_path) 54 | cached_framework_dir = generated_xcode_build_settings['FLUTTER_FRAMEWORK_DIR']; 55 | 56 | unless File.exist?(copied_framework_path) 57 | FileUtils.cp_r(File.join(cached_framework_dir, 'Flutter.framework'), copied_flutter_dir) 58 | end 59 | unless File.exist?(copied_podspec_path) 60 | FileUtils.cp(File.join(cached_framework_dir, 'Flutter.podspec'), copied_flutter_dir) 61 | end 62 | end 63 | 64 | # Keep pod path relative so it can be checked into Podfile.lock. 65 | pod 'Flutter', :path => 'Flutter' 66 | 67 | # Plugin Pods 68 | 69 | # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock 70 | # referring to absolute paths on developers' machines. 71 | system('rm -rf .symlinks') 72 | system('mkdir -p .symlinks/plugins') 73 | plugin_pods = parse_KV_file('../.flutter-plugins') 74 | plugin_pods.each do |name, path| 75 | symlink = File.join('.symlinks', 'plugins', name) 76 | File.symlink(path, symlink) 77 | pod name, :path => File.join(symlink, 'ios') 78 | end 79 | end 80 | 81 | post_install do |installer| 82 | installer.pods_project.targets.each do |target| 83 | target.build_configurations.each do |config| 84 | config.build_settings['ENABLE_BITCODE'] = 'NO' 85 | end 86 | end 87 | end 88 | -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | openapi_generator_flutter 33 | 34 | 35 | 39 | 40 | 41 | 42 | 43 | 44 | 45 |

46 | 74 | Loading indicator... 75 |
76 | 77 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /packages/openapi_code_builder/example/lib/src/api/testapi.openapi.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'testapi.openapi.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | RegisterRequest _$RegisterRequestFromJson(Map json) => 10 | RegisterRequest(email: json['email'] as String); 11 | 12 | Map _$RegisterRequestToJson(RegisterRequest instance) => 13 | {'email': instance.email}; 14 | 15 | HelloRequest _$HelloRequestFromJson(Map json) => 16 | HelloRequest(salutation: json['salutation'] as String?); 17 | 18 | Map _$HelloRequestToJson(HelloRequest instance) => 19 | {'salutation': ?instance.salutation}; 20 | 21 | HelloResponse _$HelloResponseFromJson(Map json) => 22 | HelloResponse(message: json['message'] as String?); 23 | 24 | Map _$HelloResponseToJson(HelloResponse instance) => 25 | {'message': ?instance.message}; 26 | 27 | InheritanceBase _$InheritanceBaseFromJson(Map json) => 28 | InheritanceBase(test1: json['test1'] as String?); 29 | 30 | Map _$InheritanceBaseToJson(InheritanceBase instance) => 31 | {'test1': ?instance.test1}; 32 | 33 | InheritanceChildBase _$InheritanceChildBaseFromJson( 34 | Map json, 35 | ) => InheritanceChildBase(test2: json['test2'] as String?); 36 | 37 | Map _$InheritanceChildBaseToJson( 38 | InheritanceChildBase instance, 39 | ) => {'test2': ?instance.test2}; 40 | 41 | InheritanceChild _$InheritanceChildFromJson(Map json) => 42 | InheritanceChild( 43 | test2: json['test2'] as String?, 44 | test1: json['test1'] as String?, 45 | ); 46 | 47 | Map _$InheritanceChildToJson(InheritanceChild instance) => 48 | {'test2': ?instance.test2, 'test1': ?instance.test1}; 49 | 50 | RecursiveObject _$RecursiveObjectFromJson(Map json) => 51 | RecursiveObject( 52 | parent: json['parent'] == null 53 | ? null 54 | : RecursiveObject.fromJson(json['parent'] as Map), 55 | ); 56 | 57 | Map _$RecursiveObjectToJson(RecursiveObject instance) => 58 | {'parent': ?instance.parent}; 59 | 60 | TypedAdditionalPropertiesAddProp _$TypedAdditionalPropertiesAddPropFromJson( 61 | Map json, 62 | ) => TypedAdditionalPropertiesAddProp( 63 | foo: (json['foo'] as num?)?.toInt(), 64 | bar: json['bar'] as num?, 65 | ); 66 | 67 | Map _$TypedAdditionalPropertiesAddPropToJson( 68 | TypedAdditionalPropertiesAddProp instance, 69 | ) => {'foo': ?instance.foo, 'bar': ?instance.bar}; 70 | 71 | TypedAdditionalProperties _$TypedAdditionalPropertiesFromJson( 72 | Map json, 73 | ) => TypedAdditionalProperties(); 74 | 75 | Map _$TypedAdditionalPropertiesToJson( 76 | TypedAdditionalProperties instance, 77 | ) => {}; 78 | 79 | UuidExampleMessageIdGetResponseBody200 80 | _$UuidExampleMessageIdGetResponseBody200FromJson(Map json) => 81 | UuidExampleMessageIdGetResponseBody200( 82 | id: const ApiUuidJsonConverter().fromJson(json['id'] as String), 83 | ); 84 | 85 | Map _$UuidExampleMessageIdGetResponseBody200ToJson( 86 | UuidExampleMessageIdGetResponseBody200 instance, 87 | ) => {'id': const ApiUuidJsonConverter().toJson(instance.id)}; 88 | -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /packages/openapi_base/.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | xmlns:android 14 | 15 | ^$ 16 | 17 | 18 | 19 |
20 |
21 | 22 | 23 | 24 | xmlns:.* 25 | 26 | ^$ 27 | 28 | 29 | BY_NAME 30 | 31 |
32 |
33 | 34 | 35 | 36 | .*:id 37 | 38 | http://schemas.android.com/apk/res/android 39 | 40 | 41 | 42 |
43 |
44 | 45 | 46 | 47 | .*:name 48 | 49 | http://schemas.android.com/apk/res/android 50 | 51 | 52 | 53 |
54 |
55 | 56 | 57 | 58 | name 59 | 60 | ^$ 61 | 62 | 63 | 64 |
65 |
66 | 67 | 68 | 69 | style 70 | 71 | ^$ 72 | 73 | 74 | 75 |
76 |
77 | 78 | 79 | 80 | .* 81 | 82 | ^$ 83 | 84 | 85 | BY_NAME 86 | 87 |
88 |
89 | 90 | 91 | 92 | .* 93 | 94 | http://schemas.android.com/apk/res/android 95 | 96 | 97 | ANDROID_ATTRIBUTE_ORDER 98 | 99 |
100 |
101 | 102 | 103 | 104 | .* 105 | 106 | .* 107 | 108 | 109 | BY_NAME 110 | 111 |
112 |
113 |
114 |
115 |
116 |
-------------------------------------------------------------------------------- /packages/openapi_code_builder/README.md: -------------------------------------------------------------------------------- 1 | # Dart OpenApi Code Generator 2 | 3 | `openapi_code_builder` generates server stubs and client libraries for open api schema yaml files. 4 | 5 | This is a `build_runner` library meant to be included in the 6 | `dev_dependencies` of your project to allow generating of 7 | dart source files for client and server stubs for 8 | OpenAPI 3.0 schema files (Only yaml is supported right now). 9 | 10 | See [directory for an example usage](example/). 11 | 12 | You can also [try out the code generator 13 | right inside your browser](https://hpoul.github.io/openapi_dart/): https://hpoul.github.io/openapi_dart/ 14 | 15 | ![Flutter Screenshot](_docs/screenshot.png) 16 | 17 | # Real world example 18 | 19 | See the backend for [AuthPass](https://authpass.app/) which uses auto generated 20 | openapi basically as http server. [Yaml file available on github](https://github.com/authpass/authpass-cloud/blob/master/packages/authpass_cloud_shared/lib/src/api/authpass_cloud.openapi.yaml). 21 | 22 | # Usage 23 | 24 | 1. Update `pubspec.yaml`: 25 | ```yaml 26 | dependencies: 27 | json_annotation: ^3.0.1 28 | openapi_base: any 29 | 30 | dev_dependencies: 31 | openapi_code_builder: any 32 | json_serializable: ^3.3.0 33 | build_runner: ^1.10.0 34 | ``` 35 | 2. Create your schema file into your `lib` folder 36 | with the extension `.openapi.yaml` 37 | 3. Optional: Add the base name to your schema 38 | ```yaml 39 | openapi: 3.0.0 40 | info: 41 | x-dart-name: MyApiName 42 | ``` 43 | 4. Run the build_runner: 44 | ```shell 45 | (flutter) pub run build_runner build --delete-conflicting-outputs 46 | ``` 47 | 5. Implement the server and client. (see below) 48 | 49 | 50 | # Example schema 51 | 52 | ```yaml 53 | openapi: 3.0.0 54 | info: 55 | version: 0.1.0 56 | title: Example API 57 | x-dart-name: TestApi 58 | 59 | paths: 60 | /hello/{name}: 61 | parameters: 62 | - name: name 63 | in: path 64 | required: true 65 | schema: 66 | type: string 67 | get: 68 | summary: Say Hello World to {name} 69 | responses: 70 | '200': 71 | description: OK 72 | content: 73 | application/json: 74 | schema: 75 | $ref: '#/components/schemas/HelloResponse' 76 | components: 77 | schemas: 78 | HelloResponse: 79 | properties: 80 | message: 81 | type: string 82 | description: 'The Hello World greeting ;-)' 83 | 84 | ``` 85 | 86 | # Implement Server 87 | 88 | ```dart 89 | class TestApiImpl extends TestApi { 90 | @override 91 | Future helloNameGet({String name}) async { 92 | _logger.info('Saying hi to $name'); 93 | return HelloNameGetResponse.response200( 94 | HelloResponse(message: 'Hello $name')); 95 | } 96 | } 97 | ``` 98 | 99 | ## Create a server and bind it to a port 100 | 101 | ```dart 102 | Future main() async { 103 | PrintAppender.setupLogging(); 104 | _logger.fine('Starting Server ...'); 105 | final server = OpenApiShelfServer( 106 | TestApiRouter(ApiEndpointProvider.static(TestApiImpl())), 107 | ); 108 | server.startServer(); 109 | } 110 | ``` 111 | 112 | # Implement Client 113 | 114 | ```dart 115 | Future main() async { 116 | final requestSender = HttpRequestSender(); 117 | final client = TestApiClient( 118 | Uri.parse('http://localhost:8000'), 119 | requestSender); 120 | final blubb = await client.helloNameGet(name: 'Blubb'); 121 | blubb.map( 122 | on200: (response) => _logger.info('Success: ****${response.body.message}'), 123 | ); 124 | _logger.info('Response: $blubb'); 125 | requestSender.dispose(); 126 | } 127 | ``` 128 | 129 | # Try it out 130 | 131 | Run in `openapi_dart/packages/openapi_code_builder/example` 132 | 133 | ## Server 134 | 135 | ```shell 136 | dart run bin/example_server.dart 137 | ``` 138 | 139 | ![](_docs/screenshot_server.png) 140 | 141 | ## Client 142 | 143 | ```shell 144 | dart run bin/example_client.dart 145 | ``` 146 | 147 | ![](_docs/screenshot_client.png) 148 | -------------------------------------------------------------------------------- /packages/openapi_code_builder/example/lib/src/api/testapi.openapi.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.0 2 | info: 3 | version: 0.1.0 4 | title: Example Api 5 | x-dart-name: TestApi 6 | 7 | paths: 8 | /user/register: 9 | post: 10 | summary: Create new user 11 | requestBody: 12 | required: true 13 | content: 14 | application/json: 15 | schema: 16 | $ref: '#/components/schemas/RegisterRequest' 17 | responses: 18 | '200': 19 | description: "OK\nmulti\nline" 20 | /hello/{name}/html: 21 | parameters: 22 | - name: name 23 | in: path 24 | required: true 25 | schema: 26 | type: string 27 | get: 28 | summary: Say Hello World to {name} with a nice html page. 29 | responses: 30 | '200': 31 | description: OK 32 | content: 33 | text/html: 34 | schema: 35 | type: string 36 | /hello/{name}: 37 | parameters: 38 | - name: name 39 | in: path 40 | required: true 41 | schema: 42 | type: string 43 | get: 44 | summary: Say Hello World to {name} 45 | parameters: 46 | - name: salutation 47 | description: Optional salutation 48 | in: query 49 | required: false 50 | schema: 51 | type: string 52 | responses: 53 | '200': 54 | description: OK 55 | content: 56 | application/json: 57 | schema: 58 | $ref: '#/components/schemas/HelloResponse' 59 | put: 60 | summary: Say Hello World to {name} with some parameters 61 | requestBody: 62 | required: true 63 | content: 64 | application/json: 65 | schema: 66 | $ref: '#/components/schemas/HelloRequest' 67 | responses: 68 | '200': 69 | description: OK 70 | content: 71 | application/json: 72 | schema: 73 | $ref: '#/components/schemas/HelloResponse' 74 | /uuidExample/{messageId}: 75 | parameters: 76 | - name: messageId 77 | in: path 78 | required: true 79 | schema: 80 | type: string 81 | format: uuid 82 | get: 83 | summary: details of uuid. 84 | responses: 85 | '200': 86 | description: OK 87 | content: 88 | application/json: 89 | schema: 90 | properties: 91 | id: 92 | type: string 93 | format: uuid 94 | required: 95 | - id 96 | /hello/integer: 97 | put: 98 | requestBody: 99 | content: 100 | application/json: 101 | schema: 102 | type: integer 103 | format: int32 104 | responses: 105 | '200': 106 | description: OK 107 | components: 108 | schemas: 109 | RegisterRequest: 110 | properties: 111 | email: 112 | type: string 113 | description: 'Email address for the current user.' 114 | required: 115 | - email 116 | HelloRequest: 117 | properties: 118 | salutation: 119 | type: string 120 | description: 'Salutation used for greetings.' 121 | HelloResponse: 122 | properties: 123 | message: 124 | type: string 125 | description: 'The Hello World greeting ;-)' 126 | InheritanceBase: 127 | properties: 128 | test1: { type: string } 129 | additionalProperties: true 130 | InheritanceChild: 131 | allOf: 132 | - $ref: "#/components/schemas/InheritanceBase" 133 | - properties: 134 | test2: { type: string } 135 | RecursiveObject: 136 | properties: 137 | parent: 138 | $ref: '#/components/schemas/RecursiveObject' 139 | TypedAdditionalProperties: 140 | additionalProperties: 141 | type: array 142 | items: 143 | type: object 144 | properties: 145 | foo: 146 | type: integer 147 | bar: 148 | type: number 149 | -------------------------------------------------------------------------------- /packages/openapi_code_builder/example/lib/src/api/petstore.openapi.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'petstore.openapi.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | Order _$OrderFromJson(Map json) => Order( 10 | id: (json['id'] as num?)?.toInt(), 11 | petId: (json['petId'] as num?)?.toInt(), 12 | quantity: (json['quantity'] as num?)?.toInt(), 13 | shipDate: json['shipDate'] == null 14 | ? null 15 | : DateTime.parse(json['shipDate'] as String), 16 | status: $enumDecodeNullable(_$OrderStatusEnumMap, json['status']), 17 | complete: json['complete'] as bool? ?? false, 18 | ); 19 | 20 | Map _$OrderToJson(Order instance) => { 21 | 'id': ?instance.id, 22 | 'petId': ?instance.petId, 23 | 'quantity': ?instance.quantity, 24 | 'shipDate': ?instance.shipDate?.toIso8601String(), 25 | 'status': ?_$OrderStatusEnumMap[instance.status], 26 | 'complete': instance.complete, 27 | }; 28 | 29 | const _$OrderStatusEnumMap = { 30 | OrderStatus.placed: 'placed', 31 | OrderStatus.approved: 'approved', 32 | OrderStatus.delivered: 'delivered', 33 | }; 34 | 35 | Category _$CategoryFromJson(Map json) => 36 | Category(id: (json['id'] as num?)?.toInt(), name: json['name'] as String?); 37 | 38 | Map _$CategoryToJson(Category instance) => { 39 | 'id': ?instance.id, 40 | 'name': ?instance.name, 41 | }; 42 | 43 | User _$UserFromJson(Map json) => User( 44 | id: (json['id'] as num?)?.toInt(), 45 | username: json['username'] as String?, 46 | firstName: json['firstName'] as String?, 47 | lastName: json['lastName'] as String?, 48 | email: json['email'] as String?, 49 | password: json['password'] as String?, 50 | phone: json['phone'] as String?, 51 | userStatus: (json['userStatus'] as num?)?.toInt(), 52 | ); 53 | 54 | Map _$UserToJson(User instance) => { 55 | 'id': ?instance.id, 56 | 'username': ?instance.username, 57 | 'firstName': ?instance.firstName, 58 | 'lastName': ?instance.lastName, 59 | 'email': ?instance.email, 60 | 'password': ?instance.password, 61 | 'phone': ?instance.phone, 62 | 'userStatus': ?instance.userStatus, 63 | }; 64 | 65 | Tag _$TagFromJson(Map json) => 66 | Tag(id: (json['id'] as num?)?.toInt(), name: json['name'] as String?); 67 | 68 | Map _$TagToJson(Tag instance) => { 69 | 'id': ?instance.id, 70 | 'name': ?instance.name, 71 | }; 72 | 73 | Pet _$PetFromJson(Map json) => Pet( 74 | id: (json['id'] as num?)?.toInt(), 75 | category: json['category'] == null 76 | ? null 77 | : Category.fromJson(json['category'] as Map), 78 | name: json['name'] as String, 79 | photoUrls: (json['photoUrls'] as List) 80 | .map((e) => e as String) 81 | .toList(), 82 | tags: (json['tags'] as List?) 83 | ?.map((e) => Tag.fromJson(e as Map)) 84 | .toList(), 85 | status: $enumDecodeNullable(_$PetStatusEnumMap, json['status']), 86 | ); 87 | 88 | Map _$PetToJson(Pet instance) => { 89 | 'id': ?instance.id, 90 | 'category': ?instance.category, 91 | 'name': instance.name, 92 | 'photoUrls': instance.photoUrls, 93 | 'tags': ?instance.tags, 94 | 'status': ?_$PetStatusEnumMap[instance.status], 95 | }; 96 | 97 | const _$PetStatusEnumMap = { 98 | PetStatus.available: 'available', 99 | PetStatus.pending: 'pending', 100 | PetStatus.sold: 'sold', 101 | }; 102 | 103 | ApiResponse _$ApiResponseFromJson(Map json) => ApiResponse( 104 | code: (json['code'] as num?)?.toInt(), 105 | type: json['type'] as String?, 106 | message: json['message'] as String?, 107 | ); 108 | 109 | Map _$ApiResponseToJson(ApiResponse instance) => 110 | { 111 | 'code': ?instance.code, 112 | 'type': ?instance.type, 113 | 'message': ?instance.message, 114 | }; 115 | 116 | UpdatePetWithFormSchema _$UpdatePetWithFormSchemaFromJson( 117 | Map json, 118 | ) => UpdatePetWithFormSchema( 119 | name: json['name'] as String?, 120 | status: json['status'] as String?, 121 | ); 122 | 123 | Map _$UpdatePetWithFormSchemaToJson( 124 | UpdatePetWithFormSchema instance, 125 | ) => {'name': ?instance.name, 'status': ?instance.status}; 126 | 127 | GetInventoryResponseBody200 _$GetInventoryResponseBody200FromJson( 128 | Map json, 129 | ) => GetInventoryResponseBody200(); 130 | 131 | Map _$GetInventoryResponseBody200ToJson( 132 | GetInventoryResponseBody200 instance, 133 | ) => {}; 134 | -------------------------------------------------------------------------------- /packages/openapi_generator_flutter/lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter/services.dart' show rootBundle; 3 | import 'package:flutter_markdown/flutter_markdown.dart'; 4 | import 'package:google_fonts/google_fonts.dart'; 5 | import 'package:logging/logging.dart'; 6 | import 'package:logging_appenders/logging_appenders.dart'; 7 | import 'package:openapi_code_builder/openapi_code_builder.dart'; 8 | import 'package:url_launcher/url_launcher_string.dart'; 9 | 10 | final _logger = Logger('main'); 11 | 12 | void main() { 13 | PrintAppender.setupLogging(); 14 | runApp(const MyApp()); 15 | } 16 | 17 | class MyApp extends StatelessWidget { 18 | const MyApp({super.key}); 19 | 20 | // This widget is the root of your application. 21 | @override 22 | Widget build(BuildContext context) { 23 | return MaterialApp( 24 | title: 'Flutter Demo', 25 | theme: ThemeData( 26 | primarySwatch: Colors.blue, 27 | visualDensity: VisualDensity.adaptivePlatformDensity, 28 | ), 29 | home: const OpenApiGenerator(), 30 | ); 31 | } 32 | } 33 | 34 | class OpenApiGenerator extends StatefulWidget { 35 | const OpenApiGenerator({super.key}); 36 | 37 | @override 38 | State createState() => _OpenApiGeneratorState(); 39 | } 40 | 41 | class _OpenApiGeneratorState extends State { 42 | final _input = TextEditingController(); 43 | final _output = TextEditingController(); 44 | 45 | @override 46 | void initState() { 47 | super.initState(); 48 | rootBundle.loadString('assets/petstore.schema.yaml').then((value) { 49 | _input.text = value; 50 | _updateInput(value); 51 | }); 52 | } 53 | 54 | @override 55 | Widget build(BuildContext context) { 56 | final monoFont = GoogleFonts.ubuntuMono(); 57 | return Scaffold( 58 | appBar: AppBar( 59 | title: const Text('OpenAPI Generator'), 60 | ), 61 | body: Column( 62 | children: [ 63 | Markdown( 64 | onTapLink: (text, href, title) { 65 | launchUrlString(href!); 66 | }, 67 | shrinkWrap: true, 68 | data: ''' 69 | # OpenAPI Generator 70 | 71 | Generates dart code for client AND server applications from OpenAPI 3.0 72 | yaml schema file. Typically this is used in a project using 73 | build_runner. This is just a quick example what kind of code is generated :-) 74 | 75 | See [GitHub project for details](https://github.com/hpoul/openapi_dart). 76 | ''', 77 | ), 78 | Expanded( 79 | child: Row( 80 | children: [ 81 | CodeWidget( 82 | labelText: 'OpenApi 3.0 yaml', 83 | controller: _input, 84 | onChanged: _updateInput, 85 | style: monoFont, 86 | ), 87 | Container( 88 | width: 4, 89 | height: double.infinity, 90 | color: Theme.of(context).primaryColor, 91 | ), 92 | CodeWidget( 93 | labelText: 'Generated Dart Client/Server stubs', 94 | controller: _output, 95 | onChanged: _updateInput, 96 | style: monoFont, 97 | ), 98 | ], 99 | ), 100 | ), 101 | ], 102 | ), 103 | ); 104 | } 105 | 106 | Future _updateInput(String value) async { 107 | try { 108 | final api = OpenApiCodeBuilderUtils.loadApiFromYaml(value); 109 | final generator = OpenApiLibraryGenerator( 110 | api, 111 | baseName: 'ExampleApi', 112 | partFileName: 'example.dart', 113 | ); 114 | final out = OpenApiCodeBuilderUtils.formatLibrary(generator.generate(), 115 | useNullSafetySyntax: true); 116 | _output.text = out; 117 | _logger.info('Updated output.'); 118 | } catch (e, stackTrace) { 119 | _logger.warning('Error while generating library.', e, stackTrace); 120 | } 121 | } 122 | } 123 | 124 | class CodeWidget extends StatelessWidget { 125 | const CodeWidget({ 126 | super.key, 127 | required this.controller, 128 | required this.onChanged, 129 | this.style, 130 | this.labelText, 131 | }); 132 | 133 | final TextEditingController controller; 134 | final void Function(String changed) onChanged; 135 | final TextStyle? style; 136 | final String? labelText; 137 | 138 | @override 139 | Widget build(BuildContext context) { 140 | return Expanded( 141 | child: Container( 142 | height: double.infinity, 143 | padding: const EdgeInsets.all(8.0), 144 | child: TextField( 145 | decoration: InputDecoration( 146 | labelText: labelText, 147 | border: const OutlineInputBorder(), 148 | ), 149 | enabled: true, 150 | controller: controller, 151 | maxLines: null, 152 | onChanged: onChanged, 153 | style: style, 154 | ), 155 | ), 156 | ); 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /packages/openapi_base/lib/src/util/shelf_cookie/cookie_parser.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:collection/collection.dart' show IterableExtension; 4 | import 'package:shelf/shelf.dart'; 5 | 6 | /// Parses cookies from the `Cookie` header of a [Request]. 7 | /// 8 | /// Stores all cookies in a [cookies] list, and has convenience 9 | /// methods to manipulate this list. 10 | /// 11 | /// `toString()` method converts list items to a `Set-Cookie` 12 | /// HTTP header value according to RFC 2109 spec (deprecated). 13 | class CookieParser { 14 | /// Creates a new [CookieParser] by parsing the `Cookie` header [value]. 15 | CookieParser.fromCookieValue(String? value) { 16 | if (value != null) { 17 | cookies.addAll(_parseCookieString(value)); 18 | } 19 | } 20 | 21 | /// Factory constructor to create a new instance from request [headers]. 22 | factory CookieParser.fromHeader(Map headers) { 23 | return CookieParser.fromCookieValue( 24 | headers[HttpHeaders.cookieHeader] as String?, 25 | ); 26 | } 27 | 28 | /// A list of parsed cookies. 29 | final List cookies = []; 30 | 31 | /// Denotes whether the [cookies] list is empty. 32 | bool get isEmpty => cookies.isEmpty; 33 | 34 | /// Retrieves a cookie by [name]. 35 | Cookie? get(String name) => 36 | cookies.firstWhereOrNull((Cookie cookie) => cookie.name == name); 37 | 38 | /// Adds a new cookie to [cookies] list. 39 | Cookie set( 40 | String name, 41 | String value, { 42 | String? domain, 43 | String? path, 44 | DateTime? expires, 45 | bool? httpOnly, 46 | bool? secure, 47 | int? maxAge, 48 | }) { 49 | final cookie = Cookie(name, value); 50 | if (domain != null) { 51 | cookie.domain = domain; 52 | } 53 | if (path != null) { 54 | cookie.path = path; 55 | } 56 | if (expires != null) { 57 | cookie.expires = expires; 58 | } 59 | if (httpOnly != null) { 60 | cookie.httpOnly = httpOnly; 61 | } 62 | if (secure != null) { 63 | cookie.secure = secure; 64 | } 65 | if (maxAge != null) { 66 | cookie.maxAge = maxAge; 67 | } 68 | 69 | // Update existing cookie, or append new one to list. 70 | final index = cookies.indexWhere((item) => item.name == name); 71 | if (index != -1) { 72 | cookies.replaceRange(index, index + 1, [cookie]); 73 | } else { 74 | cookies.add(cookie); 75 | } 76 | return cookie; 77 | } 78 | 79 | /// Removes a cookie from list by [name]. 80 | void remove(String name) => 81 | cookies.removeWhere((Cookie cookie) => cookie.name == name); 82 | 83 | /// Clears the cookie list. 84 | void clear() => cookies.clear(); 85 | 86 | /// Converts the cookies to a string value to use in a `Set-Cookie` header. 87 | /// 88 | /// This implements the old RFC 2109 spec, which allowed for multiple 89 | /// cookies to be folded into a single `Set-Cookie` header value, 90 | /// separated by commas. 91 | /// 92 | /// As of RFC 6265, this folded mechanism is deprecated in favour of 93 | /// a multi-header approach. 94 | /// 95 | /// Unfortunately, Shelf doesn't currently support multiple headers 96 | /// of the same type. This is an ongoing issue, but once resolved, 97 | /// this method can be deprecated. 98 | /// 99 | /// https://github.com/dart-lang/shelf/issues/44 100 | @override 101 | String toString() { 102 | return cookies.fold( 103 | '', 104 | (prev, element) => prev.isEmpty 105 | ? element.toString() 106 | : '${prev.toString()}, ${element.toString()}', 107 | ); 108 | } 109 | } 110 | 111 | /// Parse a Cookie header value according to the rules in RFC 6265. 112 | /// This function was adapted from `dart:io`. 113 | List _parseCookieString(String s) { 114 | final cookies = []; 115 | 116 | var index = 0; 117 | 118 | bool done() => index == -1 || index == s.length; 119 | 120 | void skipWS() { 121 | while (!done()) { 122 | if (s[index] != ' ' && s[index] != '\t') { 123 | return; 124 | } 125 | index++; 126 | } 127 | } 128 | 129 | String parseName() { 130 | final start = index; 131 | while (!done()) { 132 | if (s[index] == ' ' || s[index] == '\t' || s[index] == '=') { 133 | break; 134 | } 135 | index++; 136 | } 137 | return s.substring(start, index); 138 | } 139 | 140 | String parseValue() { 141 | final start = index; 142 | while (!done()) { 143 | if (s[index] == ' ' || s[index] == '\t' || s[index] == ';') { 144 | break; 145 | } 146 | index++; 147 | } 148 | return s.substring(start, index); 149 | } 150 | 151 | bool expect(String expected) { 152 | if (done()) { 153 | return false; 154 | } 155 | if (s[index] != expected) { 156 | return false; 157 | } 158 | index++; 159 | return true; 160 | } 161 | 162 | while (!done()) { 163 | skipWS(); 164 | if (done()) { 165 | continue; 166 | } 167 | final name = parseName(); 168 | skipWS(); 169 | if (!expect('=')) { 170 | index = s.indexOf(';', index); 171 | continue; 172 | } 173 | skipWS(); 174 | final value = parseValue(); 175 | try { 176 | cookies.add(Cookie(name, value)); 177 | } catch (_) { 178 | // Skip it, invalid cookie data. 179 | } 180 | skipWS(); 181 | if (done()) { 182 | continue; 183 | } 184 | if (!expect(';')) { 185 | index = s.indexOf(';', index); 186 | continue; 187 | } 188 | } 189 | 190 | return cookies; 191 | } 192 | -------------------------------------------------------------------------------- /packages/openapi_code_builder/.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 10 | 13 | 14 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | xmlns:android 24 | 25 | ^$ 26 | 27 | 28 | 29 |
30 |
31 | 32 | 33 | 34 | xmlns:.* 35 | 36 | ^$ 37 | 38 | 39 | BY_NAME 40 | 41 |
42 |
43 | 44 | 45 | 46 | .*:id 47 | 48 | http://schemas.android.com/apk/res/android 49 | 50 | 51 | 52 |
53 |
54 | 55 | 56 | 57 | .*:name 58 | 59 | http://schemas.android.com/apk/res/android 60 | 61 | 62 | 63 |
64 |
65 | 66 | 67 | 68 | name 69 | 70 | ^$ 71 | 72 | 73 | 74 |
75 |
76 | 77 | 78 | 79 | style 80 | 81 | ^$ 82 | 83 | 84 | 85 |
86 |
87 | 88 | 89 | 90 | .* 91 | 92 | ^$ 93 | 94 | 95 | BY_NAME 96 | 97 |
98 |
99 | 100 | 101 | 102 | .* 103 | 104 | http://schemas.android.com/apk/res/android 105 | 106 | 107 | ANDROID_ATTRIBUTE_ORDER 108 | 109 |
110 |
111 | 112 | 113 | 114 | .* 115 | 116 | .* 117 | 118 | 119 | BY_NAME 120 | 121 |
122 |
123 |
124 |
125 | 126 | 147 |
148 |
-------------------------------------------------------------------------------- /packages/openapi_base/lib/src/server/openapi_shelf_server.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | import 'dart:io'; 3 | import 'dart:typed_data'; 4 | 5 | // import 'package:shelf_cookie/shelf_cookie.dart'; 6 | 7 | import 'package:chunked_stream/chunked_stream.dart'; 8 | import 'package:logging/logging.dart'; 9 | import 'package:meta/meta.dart'; 10 | import 'package:openapi_base/src/openapi_base.dart'; 11 | import 'package:openapi_base/src/openapi_exception.dart'; 12 | import 'package:openapi_base/src/server/openapi_server_base.dart'; 13 | import 'package:openapi_base/src/server/stoppable_process.dart'; 14 | import 'package:openapi_base/src/util/internal_utils.dart'; 15 | import 'package:openapi_base/src/util/shelf_cookie/cookie_parser.dart'; 16 | import 'package:openapi_base/src/util/shelf_cookie/shelf_cookie.dart'; 17 | import 'package:shelf/shelf.dart' as shelf; 18 | import 'package:shelf/shelf_io.dart' as io; 19 | import 'package:uri/uri.dart'; 20 | 21 | final _logger = Logger('openapi_shelf_server'); 22 | 23 | class OpenApiShelfServer extends OpenApiServerBase { 24 | OpenApiShelfServer(this.router, {this.customizePipeline = identity}); 25 | 26 | final OpenApiServerRouterBase router; 27 | final shelf.Pipeline Function(shelf.Pipeline pipeline) customizePipeline; 28 | 29 | @protected 30 | shelf.Handler preparePipeline() { 31 | final pipeline = const shelf.Pipeline() 32 | .addMiddleware(cookieParser()) 33 | .addMiddleware(shelf.logRequests()) 34 | .addMiddleware(_handleExceptions()); 35 | 36 | return customizePipeline(pipeline).addHandler(_handleRequest); 37 | } 38 | 39 | @override 40 | Future startServer({ 41 | String address = 'localhost', 42 | int port = 8080, 43 | SecurityContext? securityContext, 44 | int? backlog, 45 | bool shared = false, 46 | String? poweredByHeader = 'Dart with package:shelf', 47 | }) async { 48 | final server = await io.serve( 49 | preparePipeline(), 50 | address, 51 | port, 52 | securityContext: securityContext, 53 | backlog: backlog, 54 | shared: shared, 55 | poweredByHeader: poweredByHeader, 56 | ); 57 | _logger 58 | .info('Serving at http${''}://${server.address.host}:${server.port}'); 59 | return StoppableProcess((reason) async { 60 | _logger.info('Stopping server... ($reason)'); 61 | await server.close(); 62 | _logger.info('Successfully stopped server.'); 63 | }); 64 | } 65 | 66 | static shelf.Middleware _handleExceptions() { 67 | return (shelf.Handler innerHandler) { 68 | return (shelf.Request request) async { 69 | try { 70 | return await innerHandler(request); 71 | } on OpenApiResponseException catch (e, stackTrace) { 72 | _logger.fine( 73 | 'response exception during request handling', 74 | e, 75 | stackTrace, 76 | ); 77 | return shelf.Response(e.status, body: e.message); 78 | } catch (e, stackTrace) { 79 | _logger.warning('Error while handling request.', e, stackTrace); 80 | rethrow; 81 | } 82 | }; 83 | }; 84 | } 85 | 86 | // 87 | // Future _handleRequestWithExceptions( 88 | // shelf.Request request) async { 89 | // try { 90 | // return await _handleRequest(request); 91 | // } on OpenApiResponseException catch (e, stackTrace) { 92 | // _logger.fine('response exception during request handling', e, stackTrace); 93 | // return shelf.Response(e.status, body: e.message); 94 | // } catch (e, stackTrace) { 95 | // _logger.warning('Error while handling request.', e, stackTrace); 96 | // rethrow; 97 | // } 98 | // } 99 | 100 | Future _handleRequest(shelf.Request request) async { 101 | final operation = operationFromString(request.method); 102 | _logger.fine('handling request. ${request.method} ${request.url}'); 103 | final url = request.url.replace(path: '/${request.url.path}'); 104 | for (final config in router.configs) { 105 | // _logger.finest( 106 | // 'Matching $operation to $config (${config.operation} vs. $operation)'); 107 | if (config.operation != operation) { 108 | continue; 109 | } 110 | final match = config.uriParser.match(url); 111 | // _logger.finest('Matching $url against ${config.uriParser}: ' 112 | // '$match'); 113 | if (match == null) { 114 | continue; 115 | } 116 | // if only matches as prefix, ignore this match. 117 | if (match.rest.path.isNotEmpty) { 118 | _logger.finest('$url does not match ${config.uriParser}, ' 119 | 'remaining path: {${match.rest.path}}: ${match.rest}'); 120 | continue; 121 | } 122 | // TODO handle security constraints. 123 | final shelfRequest = ShelfRequest(request, match); 124 | final response = await config.handler(shelfRequest); 125 | Object? body; 126 | if (response is OpenApiResponseBodyJson) { 127 | assert(response.contentType.isJson); 128 | body = json.encode(response.bodyJson); 129 | } else if (response is OpenApiResponseBodyString) { 130 | assert(response.contentType.isString); 131 | body = response.body; 132 | } else if (response is OpenApiResponseBodyBinary) { 133 | final responseBinary = response as OpenApiResponseBodyBinary; 134 | body = responseBinary.body; 135 | } else { 136 | body = null; 137 | // return shelf.Response(response.status); 138 | // throw StateError('Invalid response $response'); 139 | } 140 | final contentType = response.contentType; 141 | return shelf.Response( 142 | response.status, 143 | body: body, 144 | headers: { 145 | ...response.headers.map((key, value) => MapEntry(key, value.first)), 146 | if (contentType != null) ...{ 147 | HttpHeaders.contentTypeHeader: contentType.toString(), 148 | }, 149 | }, 150 | ); 151 | 152 | // return shelf.Response.ok('Ok found. $response'); 153 | } 154 | return shelf.Response.notFound('Not Found.'); 155 | } 156 | } 157 | 158 | class ShelfRequest extends OpenApiRequest { 159 | ShelfRequest(this._request, this._match) 160 | : _matchParametersDecoded = _match.parameters 161 | .map((key, value) => MapEntry(key, Uri.decodeComponent(value!))); 162 | 163 | final shelf.Request _request; 164 | 165 | // ignore: unused_field 166 | final UriMatch _match; 167 | final Map _matchParametersDecoded; 168 | 169 | List _wrapValue(String? value) { 170 | if (value == null) { 171 | return []; 172 | } 173 | return [value]; 174 | } 175 | 176 | @override 177 | List cookieParameter(String name) { 178 | final cookies = _request.context['cookies'] as CookieParser; 179 | return _wrapValue(cookies.get(name)?.value); 180 | } 181 | 182 | @override 183 | List headerParameter(String name) { 184 | return _wrapValue(_request.headers[name]); 185 | } 186 | 187 | @override 188 | List pathParameter(String name) { 189 | return _wrapValue(_matchParametersDecoded[name]); 190 | } 191 | 192 | @override 193 | List queryParameter(String name) { 194 | return _request.url.queryParametersAll[name] ?? []; 195 | } 196 | 197 | @override 198 | Future> readJsonBody() async { 199 | return (json.decode(await _request.readAsString()) 200 | as Map?)!; 201 | } 202 | 203 | @override 204 | Future readJsonBodyDynamic() async { 205 | return json.decode(await _request.readAsString()); 206 | } 207 | 208 | @override 209 | Future>> readUrlEncodedBody() async { 210 | final query = await _request.readAsString(); 211 | final map = Uri.splitQueryString(query); 212 | return map.map((key, value) => MapEntry(key, [value])); 213 | } 214 | 215 | @override 216 | Future readBodyString() async => await _request.readAsString(); 217 | 218 | @override 219 | Future readBodyBytes() async => 220 | await readByteStream(_request.read()); 221 | } 222 | -------------------------------------------------------------------------------- /packages/openapi_code_builder/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | # Defines a default set of lint rules enforced for 2 | # projects at Google. For details and rationale, 3 | # see https://github.com/dart-lang/pedantic#enabled-lints. 4 | include: package:lints/recommended.yaml 5 | 6 | analyzer: 7 | # enable-experiment: 8 | # - non-nullable 9 | strong-mode: 10 | implicit-casts: false 11 | implicit-dynamic: false 12 | errors: 13 | # treat missing required parameters as a warning (not a hint) 14 | missing_required_param: warning 15 | # treat missing returns as a warning (not a hint) 16 | missing_return: warning 17 | # allow having TODOs in the code 18 | todo: ignore 19 | 20 | linter: 21 | rules: 22 | # these rules are documented on and in the same order as 23 | # the Dart Lint rules page to make maintenance easier 24 | # http://dart-lang.github.io/linter/lints/ 25 | 26 | # HP mostly in sync with https://github.com/flutter/flutter/blob/master/analysis_options.yaml 27 | 28 | - always_declare_return_types 29 | - always_put_control_body_on_new_line 30 | # - always_put_required_named_parameters_first # we prefer having parameters in the same order as fields https://github.com/flutter/flutter/issues/10219 31 | # - always_specify_types 32 | - annotate_overrides 33 | # - avoid_annotating_with_dynamic # not yet tested 34 | # - avoid_as 35 | - avoid_bool_literals_in_conditional_expressions 36 | # - avoid_catches_without_on_clauses # not yet tested 37 | # - avoid_catching_errors # not yet tested 38 | # - avoid_classes_with_only_static_members # not yet tested 39 | # - avoid_double_and_int_checks # only useful when targeting JS runtime 40 | - avoid_empty_else 41 | - avoid_field_initializers_in_const_classes 42 | - avoid_function_literals_in_foreach_calls 43 | # - avoid_implementing_value_types # not yet tested 44 | - avoid_init_to_null 45 | # - avoid_js_rounded_ints # only useful when targeting JS runtime 46 | - avoid_null_checks_in_equality_operators 47 | # - avoid_positional_boolean_parameters # not yet tested 48 | # - avoid_private_typedef_functions # we prefer having typedef (discussion in https://github.com/flutter/flutter/pull/16356) 49 | - avoid_relative_lib_imports 50 | - avoid_renaming_method_parameters 51 | - avoid_return_types_on_setters 52 | # - avoid_returning_null # not yet tested 53 | # - avoid_returning_null_for_future # not yet tested 54 | - avoid_returning_null_for_void 55 | # - avoid_returning_this # not yet tested 56 | # - avoid_setters_without_getters # not yet tested 57 | # - avoid_shadowing_type_parameters # not yet tested 58 | # - avoid_single_cascade_in_expression_statements # not yet tested 59 | - avoid_slow_async_io 60 | - avoid_types_as_parameter_names 61 | # - avoid_types_on_closure_parameters # not yet tested 62 | - avoid_unused_constructor_parameters 63 | - avoid_void_async 64 | - await_only_futures 65 | - camel_case_extensions 66 | - camel_case_types 67 | - cancel_subscriptions 68 | # - cascade_invocations # not yet tested 69 | # - close_sinks # not reliable enough 70 | # - comment_references # blocked on https://github.com/flutter/flutter/issues/20765 71 | # - constant_identifier_names # https://github.com/dart-lang/linter/issues/204 72 | - control_flow_in_finally 73 | - curly_braces_in_flow_control_structures 74 | # - diagnostic_describe_all_properties # not yet tested 75 | - directives_ordering 76 | - empty_catches 77 | - empty_constructor_bodies 78 | - empty_statements 79 | # - file_names # not yet tested 80 | # - flutter_style_todos TODO(HP) 81 | - hash_and_equals 82 | - implementation_imports 83 | # - invariant_booleans # too many false positives: https://github.com/dart-lang/linter/issues/811 84 | - collection_methods_unrelated_type 85 | # - join_return_with_assignment # not yet tested 86 | - library_names 87 | - library_prefixes 88 | # - lines_longer_than_80_chars # not yet tested 89 | # - literal_only_boolean_expressions # too many false positives: https://github.com/dart-lang/sdk/issues/34181 90 | - no_adjacent_strings_in_list 91 | - no_duplicate_case_values 92 | - non_constant_identifier_names 93 | # - null_closures # not yet tested 94 | # - omit_local_variable_types # opposite of always_specify_types 95 | # - one_member_abstracts # too many false positives 96 | # - only_throw_errors # https://github.com/flutter/flutter/issues/5792 97 | - overridden_fields 98 | - package_names 99 | - package_prefixed_library_names 100 | # - parameter_assignments # we do this commonly 101 | - prefer_adjacent_string_concatenation 102 | - prefer_asserts_in_initializer_lists 103 | # - prefer_asserts_with_message # not yet tested 104 | - prefer_collection_literals 105 | - prefer_conditional_assignment 106 | - prefer_const_constructors 107 | - prefer_const_constructors_in_immutables 108 | - prefer_const_declarations 109 | - prefer_const_literals_to_create_immutables 110 | # - prefer_constructors_over_static_methods # not yet tested 111 | - prefer_contains 112 | # - prefer_double_quotes # opposite of prefer_single_quotes 113 | - prefer_equal_for_default_values 114 | # - prefer_expression_function_bodies # conflicts with https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#consider-using--for-short-functions-and-methods 115 | - prefer_final_fields 116 | - prefer_final_in_for_each 117 | - prefer_final_locals 118 | - prefer_for_elements_to_map_fromIterable 119 | - prefer_foreach 120 | # - prefer_function_declarations_over_variables # not yet tested 121 | - prefer_generic_function_type_aliases 122 | # - prefer_if_elements_to_conditional_expressions # not yet tested 123 | - prefer_if_null_operators 124 | - prefer_initializing_formals 125 | - prefer_inlined_adds 126 | # - prefer_int_literals # not yet tested 127 | # - prefer_interpolation_to_compose_strings # not yet tested 128 | - prefer_is_empty 129 | - prefer_is_not_empty 130 | - prefer_iterable_whereType 131 | # - prefer_mixin # https://github.com/dart-lang/language/issues/32 132 | # - prefer_null_aware_operators # disable until NNBD, see https://github.com/flutter/flutter/pull/32711#issuecomment-492930932 133 | - prefer_single_quotes 134 | - prefer_spread_collections 135 | - prefer_typing_uninitialized_variables 136 | - prefer_void_to_null 137 | # - provide_deprecation_message # not yet tested 138 | # - public_member_api_docs # enabled on a case-by-case basis; see e.g. packages/analysis_options.yaml 139 | - recursive_getters 140 | - slash_for_doc_comments 141 | # - sort_child_properties_last # not yet tested 142 | - sort_constructors_first 143 | #- sort_pub_dependencies 144 | - sort_unnamed_constructors_first 145 | - test_types_in_equals 146 | - throw_in_finally 147 | # - type_annotate_public_apis # subset of always_specify_types 148 | - type_init_formals 149 | # - unawaited_futures # https://github.com/flutter/flutter/issues/5793 150 | # - unnecessary_await_in_return # not yet tested 151 | - unnecessary_brace_in_string_interps 152 | - unnecessary_const 153 | - unnecessary_getters_setters 154 | # - unnecessary_lambdas # https://github.com/dart-lang/linter/issues/498 155 | - unnecessary_new 156 | - unnecessary_null_aware_assignments 157 | - unnecessary_null_in_if_null_operators 158 | - unnecessary_overrides 159 | #- unnecessary_parenthesis HP: I like parenthesis :-) 160 | - unnecessary_statements 161 | - unnecessary_this 162 | - unrelated_type_equality_checks 163 | # - unsafe_html # not yet tested 164 | - use_full_hex_values_for_flutter_colors 165 | # - use_function_type_syntax_for_parameters # not yet tested 166 | - use_rethrow_when_possible 167 | # - use_setters_to_change_properties # not yet tested 168 | # - use_string_buffers # https://github.com/dart-lang/linter/pull/664 169 | # - use_to_and_as_if_applicable # has false positives, so we prefer to catch this by code-review 170 | - valid_regexps 171 | - void_checks 172 | 173 | formatter: 174 | trailing_commas: preserve 175 | -------------------------------------------------------------------------------- /packages/openapi_code_builder/example/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | # Defines a default set of lint rules enforced for 2 | # projects at Google. For details and rationale, 3 | # see https://github.com/dart-lang/pedantic#enabled-lints. 4 | include: package:lints/recommended.yaml 5 | 6 | analyzer: 7 | # enable-experiment: 8 | # - non-nullable 9 | strong-mode: 10 | implicit-casts: false 11 | implicit-dynamic: false 12 | errors: 13 | # treat missing required parameters as a warning (not a hint) 14 | missing_required_param: warning 15 | # treat missing returns as a warning (not a hint) 16 | missing_return: warning 17 | # allow having TODOs in the code 18 | todo: ignore 19 | exclude: 20 | - lib/**/*.g.dart 21 | linter: 22 | rules: 23 | # these rules are documented on and in the same order as 24 | # the Dart Lint rules page to make maintenance easier 25 | # http://dart-lang.github.io/linter/lints/ 26 | 27 | # HP mostly in sync with https://github.com/flutter/flutter/blob/master/analysis_options.yaml 28 | 29 | - always_declare_return_types 30 | - always_put_control_body_on_new_line 31 | # - always_put_required_named_parameters_first # we prefer having parameters in the same order as fields https://github.com/flutter/flutter/issues/10219 32 | # - always_specify_types 33 | - annotate_overrides 34 | # - avoid_annotating_with_dynamic # not yet tested 35 | # - avoid_as 36 | - avoid_bool_literals_in_conditional_expressions 37 | # - avoid_catches_without_on_clauses # not yet tested 38 | # - avoid_catching_errors # not yet tested 39 | # - avoid_classes_with_only_static_members # not yet tested 40 | # - avoid_double_and_int_checks # only useful when targeting JS runtime 41 | - avoid_empty_else 42 | - avoid_field_initializers_in_const_classes 43 | - avoid_function_literals_in_foreach_calls 44 | # - avoid_implementing_value_types # not yet tested 45 | - avoid_init_to_null 46 | # - avoid_js_rounded_ints # only useful when targeting JS runtime 47 | - avoid_null_checks_in_equality_operators 48 | # - avoid_positional_boolean_parameters # not yet tested 49 | # - avoid_private_typedef_functions # we prefer having typedef (discussion in https://github.com/flutter/flutter/pull/16356) 50 | - avoid_relative_lib_imports 51 | - avoid_renaming_method_parameters 52 | - avoid_return_types_on_setters 53 | # - avoid_returning_null # not yet tested 54 | # - avoid_returning_null_for_future # not yet tested 55 | - avoid_returning_null_for_void 56 | # - avoid_returning_this # not yet tested 57 | # - avoid_setters_without_getters # not yet tested 58 | # - avoid_shadowing_type_parameters # not yet tested 59 | # - avoid_single_cascade_in_expression_statements # not yet tested 60 | - avoid_slow_async_io 61 | - avoid_types_as_parameter_names 62 | # - avoid_types_on_closure_parameters # not yet tested 63 | - avoid_unused_constructor_parameters 64 | - avoid_void_async 65 | - await_only_futures 66 | - camel_case_extensions 67 | - camel_case_types 68 | - cancel_subscriptions 69 | # - cascade_invocations # not yet tested 70 | # - close_sinks # not reliable enough 71 | # - comment_references # blocked on https://github.com/flutter/flutter/issues/20765 72 | # - constant_identifier_names # https://github.com/dart-lang/linter/issues/204 73 | - control_flow_in_finally 74 | - curly_braces_in_flow_control_structures 75 | # - diagnostic_describe_all_properties # not yet tested 76 | - directives_ordering 77 | - empty_catches 78 | - empty_constructor_bodies 79 | - empty_statements 80 | # - file_names # not yet tested 81 | # - flutter_style_todos TODO(HP) 82 | - hash_and_equals 83 | - implementation_imports 84 | # - invariant_booleans # too many false positives: https://github.com/dart-lang/linter/issues/811 85 | # - join_return_with_assignment # not yet tested 86 | - library_names 87 | - library_prefixes 88 | # - lines_longer_than_80_chars # not yet tested 89 | # - literal_only_boolean_expressions # too many false positives: https://github.com/dart-lang/sdk/issues/34181 90 | - no_adjacent_strings_in_list 91 | - no_duplicate_case_values 92 | - non_constant_identifier_names 93 | # - null_closures # not yet tested 94 | # - omit_local_variable_types # opposite of always_specify_types 95 | # - one_member_abstracts # too many false positives 96 | # - only_throw_errors # https://github.com/flutter/flutter/issues/5792 97 | - overridden_fields 98 | - package_names 99 | - package_prefixed_library_names 100 | # - parameter_assignments # we do this commonly 101 | - prefer_adjacent_string_concatenation 102 | - prefer_asserts_in_initializer_lists 103 | # - prefer_asserts_with_message # not yet tested 104 | - prefer_collection_literals 105 | - prefer_conditional_assignment 106 | - prefer_const_constructors 107 | - prefer_const_constructors_in_immutables 108 | - prefer_const_declarations 109 | - prefer_const_literals_to_create_immutables 110 | # - prefer_constructors_over_static_methods # not yet tested 111 | - prefer_contains 112 | # - prefer_double_quotes # opposite of prefer_single_quotes 113 | - prefer_equal_for_default_values 114 | # - prefer_expression_function_bodies # conflicts with https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#consider-using--for-short-functions-and-methods 115 | - prefer_final_fields 116 | - prefer_final_in_for_each 117 | - prefer_final_locals 118 | - prefer_for_elements_to_map_fromIterable 119 | - prefer_foreach 120 | # - prefer_function_declarations_over_variables # not yet tested 121 | - prefer_generic_function_type_aliases 122 | # - prefer_if_elements_to_conditional_expressions # not yet tested 123 | - prefer_if_null_operators 124 | - prefer_initializing_formals 125 | - prefer_inlined_adds 126 | # - prefer_int_literals # not yet tested 127 | # - prefer_interpolation_to_compose_strings # not yet tested 128 | - prefer_is_empty 129 | - prefer_is_not_empty 130 | - prefer_iterable_whereType 131 | # - prefer_mixin # https://github.com/dart-lang/language/issues/32 132 | # - prefer_null_aware_operators # disable until NNBD, see https://github.com/flutter/flutter/pull/32711#issuecomment-492930932 133 | - prefer_single_quotes 134 | - prefer_spread_collections 135 | - prefer_typing_uninitialized_variables 136 | - prefer_void_to_null 137 | # - provide_deprecation_message # not yet tested 138 | # - public_member_api_docs # enabled on a case-by-case basis; see e.g. packages/analysis_options.yaml 139 | - recursive_getters 140 | - slash_for_doc_comments 141 | # - sort_child_properties_last # not yet tested 142 | - sort_constructors_first 143 | #- sort_pub_dependencies 144 | - sort_unnamed_constructors_first 145 | - test_types_in_equals 146 | - throw_in_finally 147 | # - type_annotate_public_apis # subset of always_specify_types 148 | - type_init_formals 149 | # - unawaited_futures # https://github.com/flutter/flutter/issues/5793 150 | # - unnecessary_await_in_return # not yet tested 151 | - unnecessary_brace_in_string_interps 152 | - unnecessary_const 153 | - unnecessary_getters_setters 154 | # - unnecessary_lambdas # https://github.com/dart-lang/linter/issues/498 155 | - unnecessary_new 156 | - unnecessary_null_aware_assignments 157 | - unnecessary_null_in_if_null_operators 158 | - unnecessary_overrides 159 | #- unnecessary_parenthesis HP: I like parenthesis :-) 160 | - unnecessary_statements 161 | - unnecessary_this 162 | - unrelated_type_equality_checks 163 | # - unsafe_html # not yet tested 164 | - use_full_hex_values_for_flutter_colors 165 | # - use_function_type_syntax_for_parameters # not yet tested 166 | - use_rethrow_when_possible 167 | # - use_setters_to_change_properties # not yet tested 168 | # - use_string_buffers # https://github.com/dart-lang/linter/pull/664 169 | # - use_to_and_as_if_applicable # has false positives, so we prefer to catch this by code-review 170 | - valid_regexps 171 | - void_checks 172 | 173 | formatter: 174 | trailing_commas: preserve 175 | -------------------------------------------------------------------------------- /packages/openapi_base/pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | async: 5 | dependency: transitive 6 | description: 7 | name: async 8 | sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" 9 | url: "https://pub.dev" 10 | source: hosted 11 | version: "2.11.0" 12 | boolean_selector: 13 | dependency: transitive 14 | description: 15 | name: boolean_selector 16 | sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" 17 | url: "https://pub.dev" 18 | source: hosted 19 | version: "2.1.1" 20 | chunked_stream: 21 | dependency: "direct main" 22 | description: 23 | name: chunked_stream 24 | sha256: b2fde5f81d780f0c1699b8347cae2e413412ae947fc6e64727cc48c6bb54c95c 25 | url: "https://pub.dev" 26 | source: hosted 27 | version: "1.4.2" 28 | clock: 29 | dependency: transitive 30 | description: 31 | name: clock 32 | sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf 33 | url: "https://pub.dev" 34 | source: hosted 35 | version: "1.1.1" 36 | codable_forked: 37 | dependency: transitive 38 | description: 39 | name: codable_forked 40 | sha256: "902e6f90fa4d97be2d02931d0a6e555e83252fd2f8b632e26a6385c50964e473" 41 | url: "https://pub.dev" 42 | source: hosted 43 | version: "1.0.0+3" 44 | collection: 45 | dependency: "direct main" 46 | description: 47 | name: collection 48 | sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf 49 | url: "https://pub.dev" 50 | source: hosted 51 | version: "1.19.0" 52 | crypto: 53 | dependency: transitive 54 | description: 55 | name: crypto 56 | sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab 57 | url: "https://pub.dev" 58 | source: hosted 59 | version: "3.0.3" 60 | dio: 61 | dependency: transitive 62 | description: 63 | name: dio 64 | sha256: "797e1e341c3dd2f69f2dad42564a6feff3bfb87187d05abb93b9609e6f1645c3" 65 | url: "https://pub.dev" 66 | source: hosted 67 | version: "5.4.0" 68 | fixnum: 69 | dependency: transitive 70 | description: 71 | name: fixnum 72 | sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1" 73 | url: "https://pub.dev" 74 | source: hosted 75 | version: "1.1.0" 76 | http: 77 | dependency: "direct main" 78 | description: 79 | name: http 80 | sha256: a2bbf9d017fcced29139daa8ed2bba4ece450ab222871df93ca9eec6f80c34ba 81 | url: "https://pub.dev" 82 | source: hosted 83 | version: "1.2.0" 84 | http_parser: 85 | dependency: "direct main" 86 | description: 87 | name: http_parser 88 | sha256: "40f592dd352890c3b60fec1b68e786cefb9603e05ff303dbc4dda49b304ecdf4" 89 | url: "https://pub.dev" 90 | source: hosted 91 | version: "4.1.0" 92 | intl: 93 | dependency: transitive 94 | description: 95 | name: intl 96 | sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf 97 | url: "https://pub.dev" 98 | source: hosted 99 | version: "0.19.0" 100 | json_annotation: 101 | dependency: "direct main" 102 | description: 103 | name: json_annotation 104 | sha256: b10a7b2ff83d83c777edba3c6a0f97045ddadd56c944e1a23a3fdf43a1bf4467 105 | url: "https://pub.dev" 106 | source: hosted 107 | version: "4.8.1" 108 | lints: 109 | dependency: "direct dev" 110 | description: 111 | name: lints 112 | sha256: "976c774dd944a42e83e2467f4cc670daef7eed6295b10b36ae8c85bcbf828235" 113 | url: "https://pub.dev" 114 | source: hosted 115 | version: "4.0.0" 116 | logging: 117 | dependency: "direct main" 118 | description: 119 | name: logging 120 | sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340" 121 | url: "https://pub.dev" 122 | source: hosted 123 | version: "1.2.0" 124 | logging_appenders: 125 | dependency: "direct main" 126 | description: 127 | name: logging_appenders 128 | sha256: "1fb8a008c04246f4677a0d034d69779a5975e56e02573a5162240239b247e239" 129 | url: "https://pub.dev" 130 | source: hosted 131 | version: "1.2.0+1" 132 | matcher: 133 | dependency: transitive 134 | description: 135 | name: matcher 136 | sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb 137 | url: "https://pub.dev" 138 | source: hosted 139 | version: "0.12.16+1" 140 | meta: 141 | dependency: "direct main" 142 | description: 143 | name: meta 144 | sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 145 | url: "https://pub.dev" 146 | source: hosted 147 | version: "1.11.0" 148 | open_api_forked: 149 | dependency: "direct main" 150 | description: 151 | name: open_api_forked 152 | sha256: e815a0adbb290b6b460c48808de2b393f95522b1016cdb5d54cc8098cc8d5d2f 153 | url: "https://pub.dev" 154 | source: hosted 155 | version: "3.0.0+6" 156 | path: 157 | dependency: transitive 158 | description: 159 | name: path 160 | sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" 161 | url: "https://pub.dev" 162 | source: hosted 163 | version: "1.9.0" 164 | quiver: 165 | dependency: transitive 166 | description: 167 | name: quiver 168 | sha256: b1c1ac5ce6688d77f65f3375a9abb9319b3cb32486bdc7a1e0fdf004d7ba4e47 169 | url: "https://pub.dev" 170 | source: hosted 171 | version: "3.2.1" 172 | shelf: 173 | dependency: "direct main" 174 | description: 175 | name: shelf 176 | sha256: ad29c505aee705f41a4d8963641f91ac4cee3c8fad5947e033390a7bd8180fa4 177 | url: "https://pub.dev" 178 | source: hosted 179 | version: "1.4.1" 180 | source_span: 181 | dependency: transitive 182 | description: 183 | name: source_span 184 | sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" 185 | url: "https://pub.dev" 186 | source: hosted 187 | version: "1.10.0" 188 | sprintf: 189 | dependency: transitive 190 | description: 191 | name: sprintf 192 | sha256: "1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23" 193 | url: "https://pub.dev" 194 | source: hosted 195 | version: "7.0.0" 196 | stack_trace: 197 | dependency: transitive 198 | description: 199 | name: stack_trace 200 | sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" 201 | url: "https://pub.dev" 202 | source: hosted 203 | version: "1.11.1" 204 | stream_channel: 205 | dependency: transitive 206 | description: 207 | name: stream_channel 208 | sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 209 | url: "https://pub.dev" 210 | source: hosted 211 | version: "2.1.2" 212 | string_scanner: 213 | dependency: transitive 214 | description: 215 | name: string_scanner 216 | sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" 217 | url: "https://pub.dev" 218 | source: hosted 219 | version: "1.2.0" 220 | term_glyph: 221 | dependency: transitive 222 | description: 223 | name: term_glyph 224 | sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 225 | url: "https://pub.dev" 226 | source: hosted 227 | version: "1.2.1" 228 | test_api: 229 | dependency: transitive 230 | description: 231 | name: test_api 232 | sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f" 233 | url: "https://pub.dev" 234 | source: hosted 235 | version: "0.7.0" 236 | typed_data: 237 | dependency: transitive 238 | description: 239 | name: typed_data 240 | sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c 241 | url: "https://pub.dev" 242 | source: hosted 243 | version: "1.3.2" 244 | uri: 245 | dependency: "direct main" 246 | description: 247 | name: uri 248 | sha256: "889eea21e953187c6099802b7b4cf5219ba8f3518f604a1033064d45b1b8268a" 249 | url: "https://pub.dev" 250 | source: hosted 251 | version: "1.0.0" 252 | uuid: 253 | dependency: "direct main" 254 | description: 255 | name: uuid 256 | sha256: cd210a09f7c18cbe5a02511718e0334de6559871052c90a90c0cca46a4aa81c8 257 | url: "https://pub.dev" 258 | source: hosted 259 | version: "4.3.3" 260 | web: 261 | dependency: transitive 262 | description: 263 | name: web 264 | sha256: "4188706108906f002b3a293509234588823c8c979dc83304e229ff400c996b05" 265 | url: "https://pub.dev" 266 | source: hosted 267 | version: "0.4.2" 268 | sdks: 269 | dart: ">=3.4.0 <4.0.0" 270 | -------------------------------------------------------------------------------- /packages/openapi_base/lib/src/openapi_base.dart: -------------------------------------------------------------------------------- 1 | import 'dart:typed_data'; 2 | 3 | import 'package:meta/meta.dart'; 4 | import 'package:openapi_base/src/openapi_client_base.dart'; 5 | import 'package:openapi_base/src/openapi_content_type.dart'; 6 | import 'package:openapi_base/src/openapi_exception.dart'; 7 | import 'package:uri/uri.dart'; 8 | 9 | abstract class OpenApiRequest { 10 | List headerParameter(String name); 11 | 12 | List cookieParameter(String name); 13 | 14 | List pathParameter(String name); 15 | 16 | List queryParameter(String name); 17 | 18 | Future> readJsonBody(); 19 | 20 | Future readJsonBodyDynamic(); 21 | 22 | Future>> readUrlEncodedBody(); 23 | 24 | Future> readUrlEncodedBodyFlat() async => 25 | (await readUrlEncodedBody()) 26 | .map((key, value) => MapEntry(key, value.first)); 27 | 28 | Future readBodyString(); 29 | 30 | Future readBodyBytes(); 31 | } 32 | 33 | abstract class OpenApiResponseWithBody extends OpenApiResponse { 34 | @override 35 | OpenApiContentType get contentType; 36 | } 37 | 38 | abstract class OpenApiResponseBodyJson extends OpenApiResponseWithBody { 39 | Map get bodyJson; 40 | } 41 | 42 | abstract class OpenApiResponseBodyString extends OpenApiResponseWithBody { 43 | String get body; 44 | } 45 | 46 | abstract class OpenApiResponseBodyBinary { 47 | Uint8List get body; 48 | } 49 | 50 | abstract class OpenApiResponse { 51 | int get status; 52 | 53 | OpenApiContentType? get contentType; 54 | 55 | // Map bodyJson; 56 | final Map> headers = {}; 57 | 58 | @override 59 | String toString() { 60 | return '$runtimeType{${propertiesToString()}'; 61 | } 62 | 63 | @protected 64 | Map propertiesToString() { 65 | return {}; 66 | } 67 | } 68 | 69 | abstract class ApiEndpoint {} 70 | 71 | typedef RouteHandler = Future Function(OpenApiRequest request); 72 | 73 | //typedef ServiceProvider = FutureOr Function(Future callback(T)); 74 | typedef ApiEndpointCallback = Future 75 | Function(ENDPOINT impl); 76 | 77 | abstract class ApiEndpointProvider { 78 | ApiEndpointProvider(); 79 | 80 | factory ApiEndpointProvider.static(ENDPOINT endpoint) { 81 | return StaticEndpointProvider(endpoint); 82 | } 83 | 84 | Future invoke( 85 | OpenApiRequest request, 86 | ApiEndpointCallback callback, 87 | ); 88 | } 89 | 90 | class StaticEndpointProvider 91 | extends ApiEndpointProvider { 92 | StaticEndpointProvider(this.endpoint); 93 | 94 | final ENDPOINT endpoint; 95 | 96 | @override 97 | Future invoke( 98 | OpenApiRequest request, 99 | ApiEndpointCallback callback, 100 | ) async { 101 | return await callback(endpoint); 102 | } 103 | } 104 | 105 | //typedef ServiceProvider = FutureOr< 106 | // U> Function(ServiceProviderCallback impl); 107 | 108 | abstract class OpenApiServerRouterBase { 109 | OpenApiServerRouterBase() { 110 | configure(); 111 | } 112 | 113 | final List configs = []; 114 | 115 | @protected 116 | void configure(); 117 | 118 | @protected 119 | void addRoute( 120 | String path, 121 | String operation, 122 | RouteHandler handle, { 123 | required List security, 124 | }) { 125 | configs.add( 126 | RouteConfig( 127 | path, 128 | operationFromString(operation), 129 | handle, 130 | security: security, 131 | ), 132 | ); 133 | } 134 | 135 | @protected 136 | T paramRequired({ 137 | required String name, 138 | List? value, 139 | required T Function(List value) decode, 140 | }) { 141 | if (value == null || value.isEmpty) { 142 | throw MissingParameterException(name); 143 | } 144 | return decode(value); 145 | } 146 | 147 | @protected 148 | T? paramOpt({ 149 | required String name, 150 | List? value, 151 | required T Function(List value) decode, 152 | }) { 153 | if (value == null || value.isEmpty) { 154 | return null; 155 | } 156 | return decode(value); 157 | } 158 | 159 | @protected 160 | num paramToNum(List value) { 161 | return double.parse(value.first); 162 | } 163 | 164 | @protected 165 | int paramToInt(List value) { 166 | return int.parse(value.first); 167 | } 168 | 169 | @protected 170 | String paramToString(List value) { 171 | return value.first; 172 | } 173 | 174 | @protected 175 | bool paramToBool(List value) { 176 | final str = paramToString(value).toLowerCase(); 177 | return str == 'true' || str == '1'; 178 | } 179 | } 180 | 181 | enum Operation { 182 | get, 183 | put, 184 | post, 185 | delete, 186 | options, 187 | head, 188 | patch, 189 | trace, 190 | } 191 | 192 | Map _operationsMap() { 193 | final index = Operation.get.toString().indexOf('.') + 1; 194 | return Map.fromEntries( 195 | Operation.values.map((e) => MapEntry(e.toString().substring(index), e)), 196 | ); 197 | } 198 | 199 | final Map _operations = _operationsMap(); 200 | 201 | Operation operationFromString(String operation) => 202 | _operations[operation.toLowerCase()] ?? 203 | (() => throw StateError('Invalid operation $operation'))(); 204 | 205 | class RouteConfig { 206 | RouteConfig(this.path, this.operation, this.handler, {required this.security}) 207 | : uriParser = UriParser(UriTemplate(path)); 208 | 209 | final String path; 210 | final UriParser uriParser; 211 | final Operation operation; 212 | final RouteHandler handler; 213 | final List security; 214 | 215 | @override 216 | String toString() { 217 | return '_RouteConfig{path: $path, uriParser: $uriParser,' 218 | ' operation: $operation, handler: $handler}'; 219 | } 220 | } 221 | 222 | class SecurityRequirement { 223 | SecurityRequirement({required this.schemes}); 224 | 225 | List schemes; 226 | } 227 | 228 | class SecurityRequirementScheme { 229 | SecurityRequirementScheme({required this.scheme, required this.scopes}); 230 | 231 | final SecurityScheme scheme; 232 | final List scopes; 233 | } 234 | 235 | abstract class OpenApiContent {} 236 | 237 | abstract class SecurityScheme { 238 | /// apply security data into a client side request. 239 | void applyToRequest(OpenApiClientRequest request, T data); 240 | 241 | /// extract security data from a server side request. 242 | T? fromRequest(OpenApiRequest request); 243 | } 244 | 245 | abstract class SecuritySchemeData {} 246 | 247 | enum SecuritySchemeHttpScheme { 248 | bearer, 249 | } 250 | 251 | class SecuritySchemeHttpData extends SecuritySchemeData { 252 | SecuritySchemeHttpData({this.bearerToken}); 253 | 254 | final String? bearerToken; 255 | } 256 | 257 | class SecuritySchemeHttp extends SecurityScheme { 258 | SecuritySchemeHttp({required this.scheme}); 259 | 260 | final SecuritySchemeHttpScheme scheme; 261 | static const _headerName = 'Authorization'; 262 | static const _headerPrefix = 'Bearer '; 263 | 264 | @override 265 | void applyToRequest( 266 | OpenApiClientRequest request, 267 | SecuritySchemeHttpData data, 268 | ) { 269 | request.addHeaderParameter( 270 | _headerName, 271 | ['$_headerPrefix${data.bearerToken}'], 272 | ); 273 | } 274 | 275 | @override 276 | SecuritySchemeHttpData? fromRequest(OpenApiRequest request) { 277 | final authHeader = request.headerParameter(_headerName); 278 | if (authHeader.isNotEmpty) { 279 | final auth = authHeader.first; 280 | if (auth.startsWith(_headerPrefix)) { 281 | final token = auth.substring(_headerPrefix.length); 282 | return SecuritySchemeHttpData(bearerToken: token); 283 | } 284 | } 285 | return null; 286 | } 287 | } 288 | 289 | class SecuritySchemeApiKeyData extends SecuritySchemeData { 290 | SecuritySchemeApiKeyData({required this.apiKey}); 291 | 292 | final String apiKey; 293 | } 294 | 295 | class SecuritySchemeApiKey extends SecurityScheme { 296 | SecuritySchemeApiKey({ 297 | required this.name, 298 | required this.writeToRequest, 299 | required this.readFromRequest, 300 | }); 301 | 302 | final String name; 303 | final void Function(OpenApiClientRequest request, String value) 304 | writeToRequest; 305 | final List Function(OpenApiRequest request) readFromRequest; 306 | 307 | @override 308 | void applyToRequest( 309 | OpenApiClientRequest request, 310 | SecuritySchemeApiKeyData data, 311 | ) { 312 | writeToRequest(request, data.apiKey); 313 | } 314 | 315 | @override 316 | SecuritySchemeApiKeyData? fromRequest(OpenApiRequest request) { 317 | final data = readFromRequest(request); 318 | if (data.isNotEmpty) { 319 | return SecuritySchemeApiKeyData(apiKey: data.first); 320 | } 321 | return null; 322 | } 323 | } 324 | -------------------------------------------------------------------------------- /packages/openapi_base/lib/src/openapi_client_base.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | import 'dart:typed_data'; 3 | 4 | import 'package:http/http.dart'; 5 | import 'package:logging/logging.dart'; 6 | import 'package:meta/meta.dart'; 7 | import 'package:openapi_base/src/openapi_base.dart'; 8 | import 'package:openapi_base/src/openapi_content_type.dart'; 9 | import 'package:openapi_base/src/openapi_exception.dart'; 10 | import 'package:uri/uri.dart'; 11 | 12 | final _logger = Logger('openapi_client_base'); 13 | 14 | typedef ResponseMap = R Function(T response); 15 | 16 | typedef ResponseParser = Future Function( 17 | OpenApiClientResponse response, 18 | ); 19 | 20 | /// Api sender implementing the actual HTTP protocol. 21 | /// See [HttpRequestSender]. 22 | abstract class OpenApiRequestSender { 23 | Future sendRequest( 24 | Uri baseUri, 25 | OpenApiClientRequest request, 26 | ); 27 | } 28 | 29 | /// Api sender implementing the actual HTTP protocol. 30 | /// See [HttpRequestSender]. 31 | abstract class OpenApiGetRequestSender extends OpenApiRequestSender { 32 | Stream sendGet( 33 | Uri baseUri, 34 | OpenApiClientRequest request, 35 | ); 36 | } 37 | 38 | mixin OpenApiUrlEncodeMixin { 39 | @protected 40 | List encodeString(String? value) => value == null ? [] : [value]; 41 | 42 | @protected 43 | List encodeNum(num? value) => encodeObject(value); 44 | 45 | @protected 46 | List encodeInt(int? value) => encodeObject(value); 47 | 48 | @protected 49 | List encodeBool(bool? value) => encodeObject(value); 50 | 51 | List encodeObject(Object? value) => 52 | value == null ? [] : [value.toString()]; 53 | } 54 | 55 | /// Base class for generated client classes for OpenAPI apis. 56 | abstract class OpenApiClient { 57 | Map get _securitySchemeData; 58 | 59 | void setAuth>( 60 | T security, 61 | U data, 62 | ); 63 | } 64 | 65 | abstract class OpenApiClientBase 66 | with OpenApiUrlEncodeMixin 67 | implements OpenApiClient { 68 | Uri get baseUri; 69 | 70 | OpenApiRequestSender get requestSender; 71 | 72 | @override 73 | final Map _securitySchemeData = {}; 74 | 75 | @override 76 | void setAuth>( 77 | T security, 78 | U data, 79 | ) { 80 | _securitySchemeData[security] = data; 81 | } 82 | 83 | Future sendRequest( 84 | OpenApiClientRequest request, 85 | Map> parserMap, 86 | ) async { 87 | for (final security in request.securityRequirement) { 88 | for (final scheme in security.schemes) { 89 | final data = _securitySchemeData[scheme.scheme]; 90 | if (data == null) { 91 | _logger.warning('Missing security scheme data for request.' 92 | ' $scheme to ${request.path}'); 93 | continue; 94 | } 95 | scheme.scheme.applyToRequest(request, data); 96 | } 97 | } 98 | final response = await requestSender.sendRequest(baseUri, request); 99 | final parser = 100 | parserMap[response.status.toString()] ?? parserMap['default']; 101 | if (parser == null) { 102 | throw UnexpectedResponseException( 103 | response: response, 104 | request: request, 105 | status: response.status, 106 | ); 107 | } 108 | final parsedResponse = await parser(response); 109 | parsedResponse.headers.addAll(response.headers); 110 | return parsedResponse; 111 | } 112 | 113 | Stream sendGetRequest( 114 | OpenApiClientRequest request, 115 | Map> parserMap, 116 | ) async* { 117 | final sender = requestSender; 118 | if (sender is! OpenApiGetRequestSender) { 119 | throw StateError('Require a OpenApiGetRequestSender'); 120 | } 121 | for (final security in request.securityRequirement) { 122 | for (final scheme in security.schemes) { 123 | final data = _securitySchemeData[scheme.scheme]; 124 | if (data == null) { 125 | _logger.warning('Missing security scheme data for request.' 126 | ' $scheme to ${request.path}'); 127 | continue; 128 | } 129 | scheme.scheme.applyToRequest(request, data); 130 | } 131 | } 132 | await for (final response in sender.sendGet(baseUri, request)) { 133 | final parser = 134 | parserMap[response.status.toString()] ?? parserMap['default']; 135 | if (parser == null) { 136 | throw UnexpectedResponseException( 137 | response: response, 138 | request: request, 139 | status: response.status, 140 | ); 141 | } 142 | final parsedResponse = await parser(response); 143 | parsedResponse.headers.addAll(response.headers); 144 | yield parsedResponse; 145 | } 146 | } 147 | } 148 | 149 | extension SecuritySchemeClient 150 | on SecurityScheme { 151 | T? getForClient(OpenApiClient client) { 152 | return client._securitySchemeData[this] as T?; 153 | } 154 | 155 | void setForClient(OpenApiClient client, T data) { 156 | client._securitySchemeData[this] = data; 157 | } 158 | } 159 | 160 | abstract class OpenApiClientRequestBody { 161 | bool get isBytes => false; 162 | 163 | String encodeToString(); 164 | 165 | List encodeToBytes() => throw UnimplementedError(); 166 | } 167 | 168 | class OpenApiClientRequestBodyJson extends OpenApiClientRequestBody { 169 | OpenApiClientRequestBodyJson(this.jsonMap); 170 | 171 | final /*Map*/ dynamic jsonMap; 172 | 173 | @override 174 | String encodeToString() => json.encode(jsonMap); 175 | } 176 | 177 | class OpenApiClientRequestBodyText extends OpenApiClientRequestBody { 178 | OpenApiClientRequestBodyText(this.body); 179 | 180 | final String body; 181 | 182 | @override 183 | String encodeToString() => body; 184 | } 185 | 186 | class OpenApiClientRequestBodyBinary extends OpenApiClientRequestBody { 187 | OpenApiClientRequestBodyBinary(this.body); 188 | 189 | @override 190 | bool get isBytes => true; 191 | 192 | final Uint8List body; 193 | 194 | @override 195 | List encodeToBytes() => body; 196 | 197 | @override 198 | String encodeToString() => throw UnimplementedError(); 199 | } 200 | 201 | class OpenApiClientRequest { 202 | OpenApiClientRequest(this.operation, this.path, this.securityRequirement); 203 | 204 | final String operation; 205 | final String path; 206 | final List securityRequirement; 207 | final Map> paramHeader = {}; 208 | final Map> paramCookie = {}; 209 | final Map> paramPath = {}; 210 | final Map> paramQuery = {}; 211 | OpenApiClientRequestBody? body; 212 | 213 | void setHeader(String name, String value) => paramHeader[name] = [value]; 214 | 215 | void addHeaderParameter(String name, Iterable? value) => 216 | _addParam(paramHeader, name, value); 217 | 218 | void addCookieParameter(String name, Iterable? value) => 219 | _addParam(paramCookie, name, value); 220 | 221 | void addPathParameter(String name, Iterable value) => 222 | _addParam(paramPath, name, value); 223 | 224 | void addQueryParameter(String name, Iterable? value) => 225 | _addParam(paramQuery, name, value); 226 | 227 | void _addParam( 228 | Map> paramMap, 229 | String name, 230 | Iterable? value, 231 | ) { 232 | // TODO add it, if it already exists? 233 | if (value == null) { 234 | return; 235 | } 236 | paramMap[name] = value.toList(); 237 | } 238 | 239 | void setBody(OpenApiClientRequestBody body) { 240 | this.body = body; 241 | } 242 | 243 | Uri resolveUri(Uri baseUri) { 244 | if (!baseUri.path.endsWith('/') && baseUri.pathSegments.isNotEmpty) { 245 | baseUri = baseUri.resolve('${baseUri.pathSegments.last}/'); 246 | } 247 | 248 | final uriTemplate = UriTemplate(path); 249 | final expanded = uriTemplate.expand(paramPath); 250 | final expandedUri = Uri.parse(expanded.replaceFirst(RegExp(r'^/+'), '')) 251 | .replace(queryParameters: paramQuery.isEmpty ? null : paramQuery); 252 | 253 | return baseUri.resolveUri(expandedUri); 254 | } 255 | } 256 | 257 | abstract class OpenApiClientResponse { 258 | int get status; 259 | 260 | Map> get headers; 261 | 262 | OpenApiContentType? responseContentType(); 263 | 264 | Future> responseBodyJson(); 265 | 266 | Future responseBodyJsonDynamic(); 267 | 268 | Future responseBodyString(); 269 | 270 | Future responseBodyBytes(); 271 | } 272 | 273 | /// Add a user-agent adder to the given value. 274 | class UserAgentClient extends BaseClient { 275 | UserAgentClient(this.userAgent, this._inner); 276 | 277 | final String userAgent; 278 | final Client _inner; 279 | 280 | @override 281 | Future send(BaseRequest request) { 282 | request.headers['user-agent'] = userAgent; 283 | return _inner.send(request); 284 | } 285 | } 286 | 287 | /// Allows to customize how a Client is created. 288 | /// For example acn be used to use [UserAgentClient] to add user agent header. 289 | typedef ClientCreator = Client Function(); 290 | 291 | /// [OpenApiRequestSender] implementation based on package:http for 292 | /// cross platform compatibility. 293 | class HttpRequestSender extends OpenApiRequestSender { 294 | HttpRequestSender({ 295 | ClientCreator? clientCreator, 296 | }) : clientCreator = clientCreator ?? defaultClientCreator; 297 | 298 | static var defaultClientCreator = () => Client(); 299 | 300 | Client? _client; 301 | ClientCreator clientCreator; 302 | 303 | @override 304 | Future sendRequest( 305 | Uri baseUri, 306 | OpenApiClientRequest request, 307 | ) async { 308 | _client ??= clientCreator(); 309 | 310 | final uri = request.resolveUri(baseUri); 311 | _logger.finest('Expanded Uri for request to $uri ' 312 | ' (baseUri: $baseUri)'); 313 | 314 | final req = Request(request.operation, uri); 315 | final requestBody = request.body; 316 | if (requestBody != null) { 317 | if (requestBody.isBytes) { 318 | req.bodyBytes = requestBody.encodeToBytes(); 319 | } else { 320 | req.body = requestBody.encodeToString(); 321 | } 322 | } 323 | request.paramHeader.forEach((key, value) { 324 | if (value.isNotEmpty) { 325 | req.headers[key] = value.first; 326 | } 327 | }); 328 | final response = await _client!.send(req); 329 | return HttpClientResponse(await Response.fromStream(response)); 330 | } 331 | 332 | void dispose() { 333 | _client!.close(); 334 | _client = null; 335 | } 336 | } 337 | 338 | class HttpClientResponse extends OpenApiClientResponse { 339 | HttpClientResponse(this.response); 340 | 341 | final Response response; 342 | 343 | @override 344 | Future> responseBodyJson() async { 345 | return json.decode(await responseBodyString()) as Map; 346 | } 347 | 348 | @override 349 | Future responseBodyJsonDynamic() async { 350 | return json.decode(await responseBodyString()); 351 | } 352 | 353 | @override 354 | int get status => response.statusCode; 355 | 356 | @override 357 | late final Map> headers = 358 | response.headers.map((key, value) => MapEntry(key, [value])); 359 | 360 | String? _responseContentTypeString() => response.headers['content-type']; 361 | 362 | @override 363 | OpenApiContentType? responseContentType() { 364 | if (_responseContentTypeString() case final contentTypeString?) { 365 | return OpenApiContentType.parse(contentTypeString); 366 | } 367 | return null; 368 | } 369 | 370 | @override 371 | Future responseBodyString() async { 372 | if (responseContentType() case final contentType?) { 373 | final encoding = switch (contentType.charset) { 374 | final charset? => Encoding.getByName(charset), 375 | null => null, 376 | } ?? 377 | (contentType.isJson ? utf8 : latin1); 378 | return encoding.decode(response.bodyBytes); 379 | } 380 | return response.body; 381 | } 382 | 383 | @override 384 | Future responseBodyBytes() async { 385 | return response.bodyBytes; 386 | } 387 | } 388 | 389 | abstract class HasSuccessResponse implements OpenApiResponse { 390 | BODY_TYPE requireSuccess(); 391 | } 392 | 393 | extension HasSuccessFuture on Future> { 394 | Future requireSuccess() => then((value) => value.requireSuccess()); 395 | } 396 | -------------------------------------------------------------------------------- /packages/openapi_code_builder/pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | _fe_analyzer_shared: 5 | dependency: transitive 6 | description: 7 | name: _fe_analyzer_shared 8 | sha256: "5b7468c326d2f8a4f630056404ca0d291ade42918f4a3c6233618e724f39da8e" 9 | url: "https://pub.dev" 10 | source: hosted 11 | version: "92.0.0" 12 | analyzer: 13 | dependency: transitive 14 | description: 15 | name: analyzer 16 | sha256: "70e4b1ef8003c64793a9e268a551a82869a8a96f39deb73dea28084b0e8bf75e" 17 | url: "https://pub.dev" 18 | source: hosted 19 | version: "9.0.0" 20 | args: 21 | dependency: transitive 22 | description: 23 | name: args 24 | sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04 25 | url: "https://pub.dev" 26 | source: hosted 27 | version: "2.7.0" 28 | async: 29 | dependency: transitive 30 | description: 31 | name: async 32 | sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb" 33 | url: "https://pub.dev" 34 | source: hosted 35 | version: "2.13.0" 36 | boolean_selector: 37 | dependency: transitive 38 | description: 39 | name: boolean_selector 40 | sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea" 41 | url: "https://pub.dev" 42 | source: hosted 43 | version: "2.1.2" 44 | build: 45 | dependency: "direct main" 46 | description: 47 | name: build 48 | sha256: c1668065e9ba04752570ad7e038288559d1e2ca5c6d0131c0f5f55e39e777413 49 | url: "https://pub.dev" 50 | source: hosted 51 | version: "4.0.3" 52 | built_collection: 53 | dependency: "direct main" 54 | description: 55 | name: built_collection 56 | sha256: "376e3dd27b51ea877c28d525560790aee2e6fbb5f20e2f85d5081027d94e2100" 57 | url: "https://pub.dev" 58 | source: hosted 59 | version: "5.1.1" 60 | built_value: 61 | dependency: transitive 62 | description: 63 | name: built_value 64 | sha256: "426cf75afdb23aa74bd4e471704de3f9393f3c7b04c1e2d9c6f1073ae0b8b139" 65 | url: "https://pub.dev" 66 | source: hosted 67 | version: "8.12.1" 68 | chunked_stream: 69 | dependency: transitive 70 | description: 71 | name: chunked_stream 72 | sha256: b2fde5f81d780f0c1699b8347cae2e413412ae947fc6e64727cc48c6bb54c95c 73 | url: "https://pub.dev" 74 | source: hosted 75 | version: "1.4.2" 76 | clock: 77 | dependency: transitive 78 | description: 79 | name: clock 80 | sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b 81 | url: "https://pub.dev" 82 | source: hosted 83 | version: "1.1.2" 84 | codable_forked: 85 | dependency: transitive 86 | description: 87 | name: codable_forked 88 | sha256: "902e6f90fa4d97be2d02931d0a6e555e83252fd2f8b632e26a6385c50964e473" 89 | url: "https://pub.dev" 90 | source: hosted 91 | version: "1.0.0+3" 92 | code_builder: 93 | dependency: "direct main" 94 | description: 95 | name: code_builder 96 | sha256: "11654819532ba94c34de52ff5feb52bd81cba1de00ef2ed622fd50295f9d4243" 97 | url: "https://pub.dev" 98 | source: hosted 99 | version: "4.11.0" 100 | collection: 101 | dependency: "direct main" 102 | description: 103 | name: collection 104 | sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76" 105 | url: "https://pub.dev" 106 | source: hosted 107 | version: "1.19.1" 108 | convert: 109 | dependency: transitive 110 | description: 111 | name: convert 112 | sha256: b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68 113 | url: "https://pub.dev" 114 | source: hosted 115 | version: "3.1.2" 116 | crypto: 117 | dependency: transitive 118 | description: 119 | name: crypto 120 | sha256: c8ea0233063ba03258fbcf2ca4d6dadfefe14f02fab57702265467a19f27fadf 121 | url: "https://pub.dev" 122 | source: hosted 123 | version: "3.0.7" 124 | dart_style: 125 | dependency: "direct main" 126 | description: 127 | name: dart_style 128 | sha256: a9c30492da18ff84efe2422ba2d319a89942d93e58eb0b73d32abe822ef54b7b 129 | url: "https://pub.dev" 130 | source: hosted 131 | version: "3.1.3" 132 | dio: 133 | dependency: transitive 134 | description: 135 | name: dio 136 | sha256: d90ee57923d1828ac14e492ca49440f65477f4bb1263575900be731a3dac66a9 137 | url: "https://pub.dev" 138 | source: hosted 139 | version: "5.9.0" 140 | dio_web_adapter: 141 | dependency: transitive 142 | description: 143 | name: dio_web_adapter 144 | sha256: "7586e476d70caecaf1686d21eee7247ea43ef5c345eab9e0cc3583ff13378d78" 145 | url: "https://pub.dev" 146 | source: hosted 147 | version: "2.1.1" 148 | file: 149 | dependency: transitive 150 | description: 151 | name: file 152 | sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4 153 | url: "https://pub.dev" 154 | source: hosted 155 | version: "7.0.1" 156 | fixnum: 157 | dependency: transitive 158 | description: 159 | name: fixnum 160 | sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be 161 | url: "https://pub.dev" 162 | source: hosted 163 | version: "1.1.1" 164 | glob: 165 | dependency: transitive 166 | description: 167 | name: glob 168 | sha256: c3f1ee72c96f8f78935e18aa8cecced9ab132419e8625dc187e1c2408efc20de 169 | url: "https://pub.dev" 170 | source: hosted 171 | version: "2.1.3" 172 | http: 173 | dependency: transitive 174 | description: 175 | name: http 176 | sha256: "87721a4a50b19c7f1d49001e51409bddc46303966ce89a65af4f4e6004896412" 177 | url: "https://pub.dev" 178 | source: hosted 179 | version: "1.6.0" 180 | http_parser: 181 | dependency: transitive 182 | description: 183 | name: http_parser 184 | sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571" 185 | url: "https://pub.dev" 186 | source: hosted 187 | version: "4.1.2" 188 | intl: 189 | dependency: transitive 190 | description: 191 | name: intl 192 | sha256: "3df61194eb431efc39c4ceba583b95633a403f46c9fd341e550ce0bfa50e9aa5" 193 | url: "https://pub.dev" 194 | source: hosted 195 | version: "0.20.2" 196 | json_annotation: 197 | dependency: "direct main" 198 | description: 199 | name: json_annotation 200 | sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1" 201 | url: "https://pub.dev" 202 | source: hosted 203 | version: "4.9.0" 204 | lints: 205 | dependency: "direct dev" 206 | description: 207 | name: lints 208 | sha256: a5e2b223cb7c9c8efdc663ef484fdd95bb243bff242ef5b13e26883547fce9a0 209 | url: "https://pub.dev" 210 | source: hosted 211 | version: "6.0.0" 212 | logging: 213 | dependency: "direct main" 214 | description: 215 | name: logging 216 | sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61 217 | url: "https://pub.dev" 218 | source: hosted 219 | version: "1.3.0" 220 | logging_appenders: 221 | dependency: "direct main" 222 | description: 223 | name: logging_appenders 224 | sha256: "7fefa09636824f312432721c0bf77967ab19003116650729bd202bdf98142d70" 225 | url: "https://pub.dev" 226 | source: hosted 227 | version: "1.4.0+1" 228 | matcher: 229 | dependency: transitive 230 | description: 231 | name: matcher 232 | sha256: "12956d0ad8390bbcc63ca2e1469c0619946ccb52809807067a7020d57e647aa6" 233 | url: "https://pub.dev" 234 | source: hosted 235 | version: "0.12.18" 236 | meta: 237 | dependency: "direct main" 238 | description: 239 | name: meta 240 | sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394" 241 | url: "https://pub.dev" 242 | source: hosted 243 | version: "1.17.0" 244 | mime: 245 | dependency: transitive 246 | description: 247 | name: mime 248 | sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6" 249 | url: "https://pub.dev" 250 | source: hosted 251 | version: "2.0.0" 252 | open_api_forked: 253 | dependency: "direct main" 254 | description: 255 | path: "../../deps/open-api-dart" 256 | relative: true 257 | source: path 258 | version: "3.0.0+6" 259 | openapi_base: 260 | dependency: "direct main" 261 | description: 262 | path: "../openapi_base" 263 | relative: true 264 | source: path 265 | version: "2.0.0" 266 | package_config: 267 | dependency: transitive 268 | description: 269 | name: package_config 270 | sha256: f096c55ebb7deb7e384101542bfba8c52696c1b56fca2eb62827989ef2353bbc 271 | url: "https://pub.dev" 272 | source: hosted 273 | version: "2.2.0" 274 | path: 275 | dependency: "direct main" 276 | description: 277 | name: path 278 | sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" 279 | url: "https://pub.dev" 280 | source: hosted 281 | version: "1.9.1" 282 | pub_semver: 283 | dependency: "direct main" 284 | description: 285 | name: pub_semver 286 | sha256: "5bfcf68ca79ef689f8990d1160781b4bad40a3bd5e5218ad4076ddb7f4081585" 287 | url: "https://pub.dev" 288 | source: hosted 289 | version: "2.2.0" 290 | quiver: 291 | dependency: "direct main" 292 | description: 293 | name: quiver 294 | sha256: ea0b925899e64ecdfbf9c7becb60d5b50e706ade44a85b2363be2a22d88117d2 295 | url: "https://pub.dev" 296 | source: hosted 297 | version: "3.2.2" 298 | recase: 299 | dependency: "direct main" 300 | description: 301 | name: recase 302 | sha256: e4eb4ec2dcdee52dcf99cb4ceabaffc631d7424ee55e56f280bc039737f89213 303 | url: "https://pub.dev" 304 | source: hosted 305 | version: "4.1.0" 306 | shelf: 307 | dependency: transitive 308 | description: 309 | name: shelf 310 | sha256: e7dd780a7ffb623c57850b33f43309312fc863fb6aa3d276a754bb299839ef12 311 | url: "https://pub.dev" 312 | source: hosted 313 | version: "1.4.2" 314 | source_gen: 315 | dependency: "direct main" 316 | description: 317 | name: source_gen 318 | sha256: "07b277b67e0096c45196cbddddf2d8c6ffc49342e88bf31d460ce04605ddac75" 319 | url: "https://pub.dev" 320 | source: hosted 321 | version: "4.1.1" 322 | source_span: 323 | dependency: transitive 324 | description: 325 | name: source_span 326 | sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c" 327 | url: "https://pub.dev" 328 | source: hosted 329 | version: "1.10.1" 330 | stack_trace: 331 | dependency: transitive 332 | description: 333 | name: stack_trace 334 | sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1" 335 | url: "https://pub.dev" 336 | source: hosted 337 | version: "1.12.1" 338 | stream_channel: 339 | dependency: transitive 340 | description: 341 | name: stream_channel 342 | sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d" 343 | url: "https://pub.dev" 344 | source: hosted 345 | version: "2.1.4" 346 | string_scanner: 347 | dependency: transitive 348 | description: 349 | name: string_scanner 350 | sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43" 351 | url: "https://pub.dev" 352 | source: hosted 353 | version: "1.4.1" 354 | term_glyph: 355 | dependency: transitive 356 | description: 357 | name: term_glyph 358 | sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e" 359 | url: "https://pub.dev" 360 | source: hosted 361 | version: "1.2.2" 362 | test_api: 363 | dependency: transitive 364 | description: 365 | name: test_api 366 | sha256: "19a78f63e83d3a61f00826d09bc2f60e191bf3504183c001262be6ac75589fb8" 367 | url: "https://pub.dev" 368 | source: hosted 369 | version: "0.7.8" 370 | typed_data: 371 | dependency: transitive 372 | description: 373 | name: typed_data 374 | sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006 375 | url: "https://pub.dev" 376 | source: hosted 377 | version: "1.4.0" 378 | uri: 379 | dependency: transitive 380 | description: 381 | name: uri 382 | sha256: "889eea21e953187c6099802b7b4cf5219ba8f3518f604a1033064d45b1b8268a" 383 | url: "https://pub.dev" 384 | source: hosted 385 | version: "1.0.0" 386 | uuid: 387 | dependency: transitive 388 | description: 389 | name: uuid 390 | sha256: a11b666489b1954e01d992f3d601b1804a33937b5a8fe677bd26b8a9f96f96e8 391 | url: "https://pub.dev" 392 | source: hosted 393 | version: "4.5.2" 394 | watcher: 395 | dependency: transitive 396 | description: 397 | name: watcher 398 | sha256: "592ab6e2892f67760543fb712ff0177f4ec76c031f02f5b4ff8d3fc5eb9fb61a" 399 | url: "https://pub.dev" 400 | source: hosted 401 | version: "1.1.4" 402 | web: 403 | dependency: transitive 404 | description: 405 | name: web 406 | sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a" 407 | url: "https://pub.dev" 408 | source: hosted 409 | version: "1.1.1" 410 | yaml: 411 | dependency: "direct main" 412 | description: 413 | name: yaml 414 | sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce 415 | url: "https://pub.dev" 416 | source: hosted 417 | version: "3.1.3" 418 | sdks: 419 | dart: ">=3.9.0 <4.0.0" 420 | -------------------------------------------------------------------------------- /packages/openapi_code_builder/example/pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | _fe_analyzer_shared: 5 | dependency: transitive 6 | description: 7 | name: _fe_analyzer_shared 8 | sha256: c209688d9f5a5f26b2fb47a188131a6fb9e876ae9e47af3737c0b4f58a93470d 9 | url: "https://pub.dev" 10 | source: hosted 11 | version: "91.0.0" 12 | analyzer: 13 | dependency: transitive 14 | description: 15 | name: analyzer 16 | sha256: f51c8499b35f9b26820cfe914828a6a98a94efd5cc78b37bb7d03debae3a1d08 17 | url: "https://pub.dev" 18 | source: hosted 19 | version: "8.4.1" 20 | args: 21 | dependency: transitive 22 | description: 23 | name: args 24 | sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04 25 | url: "https://pub.dev" 26 | source: hosted 27 | version: "2.7.0" 28 | async: 29 | dependency: transitive 30 | description: 31 | name: async 32 | sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb" 33 | url: "https://pub.dev" 34 | source: hosted 35 | version: "2.13.0" 36 | boolean_selector: 37 | dependency: transitive 38 | description: 39 | name: boolean_selector 40 | sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea" 41 | url: "https://pub.dev" 42 | source: hosted 43 | version: "2.1.2" 44 | build: 45 | dependency: transitive 46 | description: 47 | name: build 48 | sha256: c1668065e9ba04752570ad7e038288559d1e2ca5c6d0131c0f5f55e39e777413 49 | url: "https://pub.dev" 50 | source: hosted 51 | version: "4.0.3" 52 | build_config: 53 | dependency: transitive 54 | description: 55 | name: build_config 56 | sha256: "4f64382b97504dc2fcdf487d5aae33418e08b4703fc21249e4db6d804a4d0187" 57 | url: "https://pub.dev" 58 | source: hosted 59 | version: "1.2.0" 60 | build_daemon: 61 | dependency: transitive 62 | description: 63 | name: build_daemon 64 | sha256: bf05f6e12cfea92d3c09308d7bcdab1906cd8a179b023269eed00c071004b957 65 | url: "https://pub.dev" 66 | source: hosted 67 | version: "4.1.1" 68 | build_runner: 69 | dependency: "direct dev" 70 | description: 71 | name: build_runner 72 | sha256: "110c56ef29b5eb367b4d17fc79375fa8c18a6cd7acd92c05bb3986c17a079057" 73 | url: "https://pub.dev" 74 | source: hosted 75 | version: "2.10.4" 76 | built_collection: 77 | dependency: transitive 78 | description: 79 | name: built_collection 80 | sha256: "376e3dd27b51ea877c28d525560790aee2e6fbb5f20e2f85d5081027d94e2100" 81 | url: "https://pub.dev" 82 | source: hosted 83 | version: "5.1.1" 84 | built_value: 85 | dependency: transitive 86 | description: 87 | name: built_value 88 | sha256: "426cf75afdb23aa74bd4e471704de3f9393f3c7b04c1e2d9c6f1073ae0b8b139" 89 | url: "https://pub.dev" 90 | source: hosted 91 | version: "8.12.1" 92 | checked_yaml: 93 | dependency: transitive 94 | description: 95 | name: checked_yaml 96 | sha256: "959525d3162f249993882720d52b7e0c833978df229be20702b33d48d91de70f" 97 | url: "https://pub.dev" 98 | source: hosted 99 | version: "2.0.4" 100 | chunked_stream: 101 | dependency: transitive 102 | description: 103 | name: chunked_stream 104 | sha256: b2fde5f81d780f0c1699b8347cae2e413412ae947fc6e64727cc48c6bb54c95c 105 | url: "https://pub.dev" 106 | source: hosted 107 | version: "1.4.2" 108 | clock: 109 | dependency: transitive 110 | description: 111 | name: clock 112 | sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b 113 | url: "https://pub.dev" 114 | source: hosted 115 | version: "1.1.2" 116 | codable_forked: 117 | dependency: transitive 118 | description: 119 | name: codable_forked 120 | sha256: "902e6f90fa4d97be2d02931d0a6e555e83252fd2f8b632e26a6385c50964e473" 121 | url: "https://pub.dev" 122 | source: hosted 123 | version: "1.0.0+3" 124 | code_builder: 125 | dependency: transitive 126 | description: 127 | name: code_builder 128 | sha256: "11654819532ba94c34de52ff5feb52bd81cba1de00ef2ed622fd50295f9d4243" 129 | url: "https://pub.dev" 130 | source: hosted 131 | version: "4.11.0" 132 | collection: 133 | dependency: transitive 134 | description: 135 | name: collection 136 | sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76" 137 | url: "https://pub.dev" 138 | source: hosted 139 | version: "1.19.1" 140 | convert: 141 | dependency: transitive 142 | description: 143 | name: convert 144 | sha256: b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68 145 | url: "https://pub.dev" 146 | source: hosted 147 | version: "3.1.2" 148 | crypto: 149 | dependency: transitive 150 | description: 151 | name: crypto 152 | sha256: c8ea0233063ba03258fbcf2ca4d6dadfefe14f02fab57702265467a19f27fadf 153 | url: "https://pub.dev" 154 | source: hosted 155 | version: "3.0.7" 156 | dart_style: 157 | dependency: transitive 158 | description: 159 | name: dart_style 160 | sha256: a9c30492da18ff84efe2422ba2d319a89942d93e58eb0b73d32abe822ef54b7b 161 | url: "https://pub.dev" 162 | source: hosted 163 | version: "3.1.3" 164 | dio: 165 | dependency: transitive 166 | description: 167 | name: dio 168 | sha256: d90ee57923d1828ac14e492ca49440f65477f4bb1263575900be731a3dac66a9 169 | url: "https://pub.dev" 170 | source: hosted 171 | version: "5.9.0" 172 | dio_web_adapter: 173 | dependency: transitive 174 | description: 175 | name: dio_web_adapter 176 | sha256: "7586e476d70caecaf1686d21eee7247ea43ef5c345eab9e0cc3583ff13378d78" 177 | url: "https://pub.dev" 178 | source: hosted 179 | version: "2.1.1" 180 | file: 181 | dependency: transitive 182 | description: 183 | name: file 184 | sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4 185 | url: "https://pub.dev" 186 | source: hosted 187 | version: "7.0.1" 188 | fixnum: 189 | dependency: transitive 190 | description: 191 | name: fixnum 192 | sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be 193 | url: "https://pub.dev" 194 | source: hosted 195 | version: "1.1.1" 196 | freezed: 197 | dependency: "direct dev" 198 | description: 199 | name: freezed 200 | sha256: "13065f10e135263a4f5a4391b79a8efc5fb8106f8dd555a9e49b750b45393d77" 201 | url: "https://pub.dev" 202 | source: hosted 203 | version: "3.2.3" 204 | freezed_annotation: 205 | dependency: "direct main" 206 | description: 207 | name: freezed_annotation 208 | sha256: "7294967ff0a6d98638e7acb774aac3af2550777accd8149c90af5b014e6d44d8" 209 | url: "https://pub.dev" 210 | source: hosted 211 | version: "3.1.0" 212 | glob: 213 | dependency: transitive 214 | description: 215 | name: glob 216 | sha256: c3f1ee72c96f8f78935e18aa8cecced9ab132419e8625dc187e1c2408efc20de 217 | url: "https://pub.dev" 218 | source: hosted 219 | version: "2.1.3" 220 | graphs: 221 | dependency: transitive 222 | description: 223 | name: graphs 224 | sha256: "741bbf84165310a68ff28fe9e727332eef1407342fca52759cb21ad8177bb8d0" 225 | url: "https://pub.dev" 226 | source: hosted 227 | version: "2.3.2" 228 | http: 229 | dependency: transitive 230 | description: 231 | name: http 232 | sha256: "87721a4a50b19c7f1d49001e51409bddc46303966ce89a65af4f4e6004896412" 233 | url: "https://pub.dev" 234 | source: hosted 235 | version: "1.6.0" 236 | http_multi_server: 237 | dependency: transitive 238 | description: 239 | name: http_multi_server 240 | sha256: aa6199f908078bb1c5efb8d8638d4ae191aac11b311132c3ef48ce352fb52ef8 241 | url: "https://pub.dev" 242 | source: hosted 243 | version: "3.2.2" 244 | http_parser: 245 | dependency: transitive 246 | description: 247 | name: http_parser 248 | sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571" 249 | url: "https://pub.dev" 250 | source: hosted 251 | version: "4.1.2" 252 | intl: 253 | dependency: transitive 254 | description: 255 | name: intl 256 | sha256: "3df61194eb431efc39c4ceba583b95633a403f46c9fd341e550ce0bfa50e9aa5" 257 | url: "https://pub.dev" 258 | source: hosted 259 | version: "0.20.2" 260 | io: 261 | dependency: transitive 262 | description: 263 | name: io 264 | sha256: dfd5a80599cf0165756e3181807ed3e77daf6dd4137caaad72d0b7931597650b 265 | url: "https://pub.dev" 266 | source: hosted 267 | version: "1.0.5" 268 | json_annotation: 269 | dependency: "direct main" 270 | description: 271 | name: json_annotation 272 | sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1" 273 | url: "https://pub.dev" 274 | source: hosted 275 | version: "4.9.0" 276 | json_serializable: 277 | dependency: "direct dev" 278 | description: 279 | name: json_serializable 280 | sha256: c5b2ee75210a0f263c6c7b9eeea80553dbae96ea1bf57f02484e806a3ffdffa3 281 | url: "https://pub.dev" 282 | source: hosted 283 | version: "6.11.2" 284 | lints: 285 | dependency: "direct dev" 286 | description: 287 | name: lints 288 | sha256: a5e2b223cb7c9c8efdc663ef484fdd95bb243bff242ef5b13e26883547fce9a0 289 | url: "https://pub.dev" 290 | source: hosted 291 | version: "6.0.0" 292 | logging: 293 | dependency: "direct main" 294 | description: 295 | name: logging 296 | sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61 297 | url: "https://pub.dev" 298 | source: hosted 299 | version: "1.3.0" 300 | logging_appenders: 301 | dependency: "direct main" 302 | description: 303 | name: logging_appenders 304 | sha256: "7fefa09636824f312432721c0bf77967ab19003116650729bd202bdf98142d70" 305 | url: "https://pub.dev" 306 | source: hosted 307 | version: "1.4.0+1" 308 | matcher: 309 | dependency: transitive 310 | description: 311 | name: matcher 312 | sha256: "12956d0ad8390bbcc63ca2e1469c0619946ccb52809807067a7020d57e647aa6" 313 | url: "https://pub.dev" 314 | source: hosted 315 | version: "0.12.18" 316 | meta: 317 | dependency: transitive 318 | description: 319 | name: meta 320 | sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394" 321 | url: "https://pub.dev" 322 | source: hosted 323 | version: "1.17.0" 324 | mime: 325 | dependency: transitive 326 | description: 327 | name: mime 328 | sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6" 329 | url: "https://pub.dev" 330 | source: hosted 331 | version: "2.0.0" 332 | open_api_forked: 333 | dependency: "direct overridden" 334 | description: 335 | path: "../../../deps/open-api-dart" 336 | relative: true 337 | source: path 338 | version: "3.0.0+6" 339 | openapi_base: 340 | dependency: "direct main" 341 | description: 342 | path: "../../openapi_base" 343 | relative: true 344 | source: path 345 | version: "2.0.0" 346 | openapi_code_builder: 347 | dependency: "direct dev" 348 | description: 349 | path: ".." 350 | relative: true 351 | source: path 352 | version: "1.8.0" 353 | package_config: 354 | dependency: transitive 355 | description: 356 | name: package_config 357 | sha256: f096c55ebb7deb7e384101542bfba8c52696c1b56fca2eb62827989ef2353bbc 358 | url: "https://pub.dev" 359 | source: hosted 360 | version: "2.2.0" 361 | path: 362 | dependency: transitive 363 | description: 364 | name: path 365 | sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" 366 | url: "https://pub.dev" 367 | source: hosted 368 | version: "1.9.1" 369 | pool: 370 | dependency: transitive 371 | description: 372 | name: pool 373 | sha256: "978783255c543aa3586a1b3c21f6e9d720eb315376a915872c61ef8b5c20177d" 374 | url: "https://pub.dev" 375 | source: hosted 376 | version: "1.5.2" 377 | pub_semver: 378 | dependency: transitive 379 | description: 380 | name: pub_semver 381 | sha256: "5bfcf68ca79ef689f8990d1160781b4bad40a3bd5e5218ad4076ddb7f4081585" 382 | url: "https://pub.dev" 383 | source: hosted 384 | version: "2.2.0" 385 | pubspec_parse: 386 | dependency: transitive 387 | description: 388 | name: pubspec_parse 389 | sha256: "0560ba233314abbed0a48a2956f7f022cce7c3e1e73df540277da7544cad4082" 390 | url: "https://pub.dev" 391 | source: hosted 392 | version: "1.5.0" 393 | quiver: 394 | dependency: transitive 395 | description: 396 | name: quiver 397 | sha256: ea0b925899e64ecdfbf9c7becb60d5b50e706ade44a85b2363be2a22d88117d2 398 | url: "https://pub.dev" 399 | source: hosted 400 | version: "3.2.2" 401 | recase: 402 | dependency: transitive 403 | description: 404 | name: recase 405 | sha256: e4eb4ec2dcdee52dcf99cb4ceabaffc631d7424ee55e56f280bc039737f89213 406 | url: "https://pub.dev" 407 | source: hosted 408 | version: "4.1.0" 409 | shelf: 410 | dependency: transitive 411 | description: 412 | name: shelf 413 | sha256: e7dd780a7ffb623c57850b33f43309312fc863fb6aa3d276a754bb299839ef12 414 | url: "https://pub.dev" 415 | source: hosted 416 | version: "1.4.2" 417 | shelf_web_socket: 418 | dependency: transitive 419 | description: 420 | name: shelf_web_socket 421 | sha256: "3632775c8e90d6c9712f883e633716432a27758216dfb61bd86a8321c0580925" 422 | url: "https://pub.dev" 423 | source: hosted 424 | version: "3.0.0" 425 | source_gen: 426 | dependency: transitive 427 | description: 428 | name: source_gen 429 | sha256: "07b277b67e0096c45196cbddddf2d8c6ffc49342e88bf31d460ce04605ddac75" 430 | url: "https://pub.dev" 431 | source: hosted 432 | version: "4.1.1" 433 | source_helper: 434 | dependency: transitive 435 | description: 436 | name: source_helper 437 | sha256: "6a3c6cc82073a8797f8c4dc4572146114a39652851c157db37e964d9c7038723" 438 | url: "https://pub.dev" 439 | source: hosted 440 | version: "1.3.8" 441 | source_span: 442 | dependency: transitive 443 | description: 444 | name: source_span 445 | sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c" 446 | url: "https://pub.dev" 447 | source: hosted 448 | version: "1.10.1" 449 | stack_trace: 450 | dependency: transitive 451 | description: 452 | name: stack_trace 453 | sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1" 454 | url: "https://pub.dev" 455 | source: hosted 456 | version: "1.12.1" 457 | stream_channel: 458 | dependency: transitive 459 | description: 460 | name: stream_channel 461 | sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d" 462 | url: "https://pub.dev" 463 | source: hosted 464 | version: "2.1.4" 465 | stream_transform: 466 | dependency: transitive 467 | description: 468 | name: stream_transform 469 | sha256: ad47125e588cfd37a9a7f86c7d6356dde8dfe89d071d293f80ca9e9273a33871 470 | url: "https://pub.dev" 471 | source: hosted 472 | version: "2.1.1" 473 | string_scanner: 474 | dependency: transitive 475 | description: 476 | name: string_scanner 477 | sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43" 478 | url: "https://pub.dev" 479 | source: hosted 480 | version: "1.4.1" 481 | term_glyph: 482 | dependency: transitive 483 | description: 484 | name: term_glyph 485 | sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e" 486 | url: "https://pub.dev" 487 | source: hosted 488 | version: "1.2.2" 489 | test_api: 490 | dependency: transitive 491 | description: 492 | name: test_api 493 | sha256: "19a78f63e83d3a61f00826d09bc2f60e191bf3504183c001262be6ac75589fb8" 494 | url: "https://pub.dev" 495 | source: hosted 496 | version: "0.7.8" 497 | typed_data: 498 | dependency: transitive 499 | description: 500 | name: typed_data 501 | sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006 502 | url: "https://pub.dev" 503 | source: hosted 504 | version: "1.4.0" 505 | uri: 506 | dependency: transitive 507 | description: 508 | name: uri 509 | sha256: "889eea21e953187c6099802b7b4cf5219ba8f3518f604a1033064d45b1b8268a" 510 | url: "https://pub.dev" 511 | source: hosted 512 | version: "1.0.0" 513 | uuid: 514 | dependency: transitive 515 | description: 516 | name: uuid 517 | sha256: a11b666489b1954e01d992f3d601b1804a33937b5a8fe677bd26b8a9f96f96e8 518 | url: "https://pub.dev" 519 | source: hosted 520 | version: "4.5.2" 521 | watcher: 522 | dependency: transitive 523 | description: 524 | name: watcher 525 | sha256: "592ab6e2892f67760543fb712ff0177f4ec76c031f02f5b4ff8d3fc5eb9fb61a" 526 | url: "https://pub.dev" 527 | source: hosted 528 | version: "1.1.4" 529 | web: 530 | dependency: transitive 531 | description: 532 | name: web 533 | sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a" 534 | url: "https://pub.dev" 535 | source: hosted 536 | version: "1.1.1" 537 | web_socket: 538 | dependency: transitive 539 | description: 540 | name: web_socket 541 | sha256: "34d64019aa8e36bf9842ac014bb5d2f5586ca73df5e4d9bf5c936975cae6982c" 542 | url: "https://pub.dev" 543 | source: hosted 544 | version: "1.0.1" 545 | web_socket_channel: 546 | dependency: transitive 547 | description: 548 | name: web_socket_channel 549 | sha256: d645757fb0f4773d602444000a8131ff5d48c9e47adfe9772652dd1a4f2d45c8 550 | url: "https://pub.dev" 551 | source: hosted 552 | version: "3.0.3" 553 | yaml: 554 | dependency: transitive 555 | description: 556 | name: yaml 557 | sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce 558 | url: "https://pub.dev" 559 | source: hosted 560 | version: "3.1.3" 561 | sdks: 562 | dart: ">=3.9.0 <4.0.0" 563 | --------------------------------------------------------------------------------