From 12c560badb12daa96ac7637846a507f52bff7361 Mon Sep 17 00:00:00 2001 From: Herbert Poul Date: Sun, 7 Jun 2020 17:02:36 +0200 Subject: [PATCH 01/30] fix null pointer exception. --- lib/src/v3/security.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/v3/security.dart b/lib/src/v3/security.dart index be4a7da..668113f 100644 --- a/lib/src/v3/security.dart +++ b/lib/src/v3/security.dart @@ -246,7 +246,7 @@ class APISecurityRequirement extends APIObject { /// Each name MUST correspond to a security scheme which is declared in [APIComponents.securitySchemes]. /// /// If the security scheme is of type [APISecuritySchemeType.oauth2] or [APISecuritySchemeType.openID], then the value is a list of scope names required for the execution. For other security scheme types, the array MUST be empty. - Map> requirements; + Map> requirements = {}; void encode(KeyedArchive object) { super.encode(object); From 530d684d0a1cbf9a0971dc7e1356c35d26f7d30b Mon Sep 17 00:00:00 2001 From: Herbert Poul Date: Tue, 9 Jun 2020 15:36:57 +0200 Subject: [PATCH 02/30] add test for security requirements. --- test/v3_test.dart | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/test/v3_test.dart b/test/v3_test.dart index 2eb4bea..5df66b0 100644 --- a/test/v3_test.dart +++ b/test/v3_test.dart @@ -167,6 +167,29 @@ void main() { }); }); + group("Security", () { + test("Can parse security requirements", () { + final doc = new APIDocument.fromMap({ + "openapi": "3.0.0", + "info": {"title": "x", "version": "1"}, + "paths": { + "/foo": { + "get": { + "summary": "Lorem Ipsum", + "security": [ + { + "test": [], + } + ], + }, + }, + }, + }); + expect(doc.paths.values.first.operations.values.first.security, + hasLength(1)); + }); + }); + group("Schema", () { test("Can read/emit schema object with additionalProperties=true", () { final doc = new APIDocument.fromMap({ From d22446456d3344eded227d24158d7ec62673437f Mon Sep 17 00:00:00 2001 From: Herbert Poul Date: Wed, 24 Jun 2020 11:47:14 +0200 Subject: [PATCH 03/30] add support for security requirements. --- lib/src/v3/document.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/src/v3/document.dart b/lib/src/v3/document.dart index 3a3fa69..cd5cbff 100644 --- a/lib/src/v3/document.dart +++ b/lib/src/v3/document.dart @@ -59,9 +59,9 @@ class APIDocument extends APIObject { info = object.decodeObject("info", () => new APIInfo.empty()); servers = object.decodeObjects("servers", () => new APIServerDescription.empty()); paths = object.decodeObjectMap("paths", () => new APIPath()); - components = - object.decodeObject("components", () => new APIComponents()); - security = object.decode("security"); + components = object.decodeObject("components", () => new APIComponents()); + security = + object.decodeObjects("security", () => APISecurityRequirement.empty()); tags = object.decodeObjects("tags", () => new APITag.empty()); } From d572797397f7be702f8b8b944bbd29038cff47f1 Mon Sep 17 00:00:00 2001 From: Herbert Poul Date: Tue, 28 Jul 2020 13:40:22 +0200 Subject: [PATCH 04/30] sed -i '' 's/package:open_api/package:open_api_forked/g' `find . -name '*.dart' | xargs` --- CHANGELOG.md | 4 ++++ lib/src/object.dart | 2 +- lib/src/v2/document.dart | 14 +++++++------- lib/src/v2/header.dart | 4 ++-- lib/src/v2/metadata.dart | 2 +- lib/src/v2/operation.dart | 6 +++--- lib/src/v2/parameter.dart | 6 +++--- lib/src/v2/path.dart | 6 +++--- lib/src/v2/property.dart | 4 ++-- lib/src/v2/response.dart | 6 +++--- lib/src/v2/schema.dart | 2 +- lib/src/v2/security.dart | 4 ++-- lib/src/v3/callback.dart | 4 ++-- lib/src/v3/components.dart | 16 ++++++++-------- lib/src/v3/document.dart | 12 ++++++------ lib/src/v3/encoding.dart | 6 +++--- lib/src/v3/header.dart | 4 ++-- lib/src/v3/media_type.dart | 6 +++--- lib/src/v3/metadata.dart | 2 +- lib/src/v3/operation.dart | 18 +++++++++--------- lib/src/v3/parameter.dart | 8 ++++---- lib/src/v3/path.dart | 6 +++--- lib/src/v3/request_body.dart | 6 +++--- lib/src/v3/response.dart | 8 ++++---- lib/src/v3/schema.dart | 4 ++-- lib/src/v3/security.dart | 12 ++++++------ lib/src/v3/server.dart | 2 +- lib/v2.dart | 20 ++++++++++---------- lib/v3.dart | 34 +++++++++++++++++----------------- pubspec.yaml | 6 +++--- test/v2_test.dart | 2 +- test/v3_test.dart | 2 +- 32 files changed, 121 insertions(+), 117 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d4c236f..383ef93 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 2.0.1+1 + +- forked version to fix v3 security requirements + ## 2.0.1 - Fix bug when merging APIResponse bodies diff --git a/lib/src/object.dart b/lib/src/object.dart index 22eccfa..2c7ec61 100644 --- a/lib/src/object.dart +++ b/lib/src/object.dart @@ -29,4 +29,4 @@ class APIObject extends Coding { object.encode(key, value); }); } -} \ No newline at end of file +} diff --git a/lib/src/v2/document.dart b/lib/src/v2/document.dart index 288cec8..a2e47b9 100644 --- a/lib/src/v2/document.dart +++ b/lib/src/v2/document.dart @@ -1,11 +1,11 @@ import 'package:codable/cast.dart' as cast; -import 'package:open_api/src/object.dart'; -import 'package:open_api/src/v2/metadata.dart'; -import 'package:open_api/src/v2/parameter.dart'; -import 'package:open_api/src/v2/path.dart'; -import 'package:open_api/src/v2/response.dart'; -import 'package:open_api/src/v2/schema.dart'; -import 'package:open_api/src/v2/security.dart'; +import 'package:open_api_forked/src/object.dart'; +import 'package:open_api_forked/src/v2/metadata.dart'; +import 'package:open_api_forked/src/v2/parameter.dart'; +import 'package:open_api_forked/src/v2/path.dart'; +import 'package:open_api_forked/src/v2/response.dart'; +import 'package:open_api_forked/src/v2/schema.dart'; +import 'package:open_api_forked/src/v2/security.dart'; /// Represents an OpenAPI 2.0 specification. class APIDocument extends APIObject { diff --git a/lib/src/v2/header.dart b/lib/src/v2/header.dart index bde5d29..3cb291d 100644 --- a/lib/src/v2/header.dart +++ b/lib/src/v2/header.dart @@ -1,6 +1,6 @@ import 'package:codable/codable.dart'; -import 'package:open_api/src/v2/property.dart'; -import 'package:open_api/src/v2/types.dart'; +import 'package:open_api_forked/src/v2/property.dart'; +import 'package:open_api_forked/src/v2/types.dart'; /// Represents a header in the OpenAPI specification. class APIHeader extends APIProperty { diff --git a/lib/src/v2/metadata.dart b/lib/src/v2/metadata.dart index eca70b6..70b4ff3 100644 --- a/lib/src/v2/metadata.dart +++ b/lib/src/v2/metadata.dart @@ -1,4 +1,4 @@ -import 'package:open_api/src/object.dart'; +import 'package:open_api_forked/src/object.dart'; /// Represents a metadata for an API in the OpenAPI specification. class APIInfo extends APIObject { diff --git a/lib/src/v2/operation.dart b/lib/src/v2/operation.dart index 4e7c799..40e5908 100644 --- a/lib/src/v2/operation.dart +++ b/lib/src/v2/operation.dart @@ -1,7 +1,7 @@ import 'package:codable/cast.dart' as cast; -import 'package:open_api/src/object.dart'; -import 'package:open_api/src/v2/parameter.dart'; -import 'package:open_api/src/v2/response.dart'; +import 'package:open_api_forked/src/object.dart'; +import 'package:open_api_forked/src/v2/parameter.dart'; +import 'package:open_api_forked/src/v2/response.dart'; /// Represents a HTTP operation (a path/method pair) in the OpenAPI specification. class APIOperation extends APIObject { diff --git a/lib/src/v2/parameter.dart b/lib/src/v2/parameter.dart index da11d3f..82f815a 100644 --- a/lib/src/v2/parameter.dart +++ b/lib/src/v2/parameter.dart @@ -1,7 +1,7 @@ import 'package:codable/codable.dart'; -import 'package:open_api/src/v2/property.dart'; -import 'package:open_api/src/v2/schema.dart'; -import 'package:open_api/src/v2/types.dart'; +import 'package:open_api_forked/src/v2/property.dart'; +import 'package:open_api_forked/src/v2/schema.dart'; +import 'package:open_api_forked/src/v2/types.dart'; /// Represents a parameter location in the OpenAPI specification. enum APIParameterLocation { query, header, path, formData, body } diff --git a/lib/src/v2/path.dart b/lib/src/v2/path.dart index 19dd817..f5c2e0b 100644 --- a/lib/src/v2/path.dart +++ b/lib/src/v2/path.dart @@ -1,6 +1,6 @@ -import 'package:open_api/src/object.dart'; -import 'package:open_api/src/v2/operation.dart'; -import 'package:open_api/src/v2/parameter.dart'; +import 'package:open_api_forked/src/object.dart'; +import 'package:open_api_forked/src/v2/operation.dart'; +import 'package:open_api_forked/src/v2/parameter.dart'; /// Represents a path (also known as a route) in the OpenAPI specification. class APIPath extends APIObject { diff --git a/lib/src/v2/property.dart b/lib/src/v2/property.dart index a6a8e4c..e877846 100644 --- a/lib/src/v2/property.dart +++ b/lib/src/v2/property.dart @@ -1,5 +1,5 @@ -import 'package:open_api/src/object.dart'; -import 'package:open_api/src/v2/types.dart'; +import 'package:open_api_forked/src/object.dart'; +import 'package:open_api_forked/src/v2/types.dart'; enum APISchemaRepresentation { primitive, diff --git a/lib/src/v2/response.dart b/lib/src/v2/response.dart index 20063e5..b2761fd 100644 --- a/lib/src/v2/response.dart +++ b/lib/src/v2/response.dart @@ -1,6 +1,6 @@ -import 'package:open_api/src/object.dart'; -import 'package:open_api/src/v2/header.dart'; -import 'package:open_api/src/v2/schema.dart'; +import 'package:open_api_forked/src/object.dart'; +import 'package:open_api_forked/src/v2/header.dart'; +import 'package:open_api_forked/src/v2/schema.dart'; /// Represents an HTTP response in the OpenAPI specification. class APIResponse extends APIObject { diff --git a/lib/src/v2/schema.dart b/lib/src/v2/schema.dart index ab7837e..4b3aa52 100644 --- a/lib/src/v2/schema.dart +++ b/lib/src/v2/schema.dart @@ -1,6 +1,6 @@ import 'package:codable/cast.dart' as cast; import 'package:codable/codable.dart'; -import 'package:open_api/src/v2/property.dart'; +import 'package:open_api_forked/src/v2/property.dart'; /// Represents a schema object in the OpenAPI specification. class APISchemaObject extends APIProperty { diff --git a/lib/src/v2/security.dart b/lib/src/v2/security.dart index a7575c0..e162e47 100644 --- a/lib/src/v2/security.dart +++ b/lib/src/v2/security.dart @@ -1,6 +1,6 @@ import 'package:codable/cast.dart' as cast; -import 'package:open_api/src/object.dart'; -import 'package:open_api/src/v2/parameter.dart'; +import 'package:open_api_forked/src/object.dart'; +import 'package:open_api_forked/src/v2/parameter.dart'; /// Represents a OAuth 2.0 security scheme flow in the OpenAPI specification. enum APISecuritySchemeFlow { implicit, password, application, authorizationCode } diff --git a/lib/src/v3/callback.dart b/lib/src/v3/callback.dart index 9c3c347..0a24c87 100644 --- a/lib/src/v3/callback.dart +++ b/lib/src/v3/callback.dart @@ -1,5 +1,5 @@ -import 'package:open_api/src/object.dart'; -import 'package:open_api/src/v3/path.dart'; +import 'package:open_api_forked/src/object.dart'; +import 'package:open_api_forked/src/v3/path.dart'; /// A map of possible out-of band callbacks related to the parent operation. /// diff --git a/lib/src/v3/components.dart b/lib/src/v3/components.dart index ac45d07..67234dd 100644 --- a/lib/src/v3/components.dart +++ b/lib/src/v3/components.dart @@ -1,11 +1,11 @@ -import 'package:open_api/src/object.dart'; -import 'package:open_api/src/v3/callback.dart'; -import 'package:open_api/src/v3/header.dart'; -import 'package:open_api/src/v3/parameter.dart'; -import 'package:open_api/src/v3/request_body.dart'; -import 'package:open_api/src/v3/response.dart'; -import 'package:open_api/src/v3/schema.dart'; -import 'package:open_api/src/v3/security.dart'; +import 'package:open_api_forked/src/object.dart'; +import 'package:open_api_forked/src/v3/callback.dart'; +import 'package:open_api_forked/src/v3/header.dart'; +import 'package:open_api_forked/src/v3/parameter.dart'; +import 'package:open_api_forked/src/v3/request_body.dart'; +import 'package:open_api_forked/src/v3/response.dart'; +import 'package:open_api_forked/src/v3/schema.dart'; +import 'package:open_api_forked/src/v3/security.dart'; /// Holds a set of reusable objects for different aspects of the OAS. /// diff --git a/lib/src/v3/document.dart b/lib/src/v3/document.dart index cd5cbff..37f314e 100644 --- a/lib/src/v3/document.dart +++ b/lib/src/v3/document.dart @@ -1,9 +1,9 @@ -import 'package:open_api/src/object.dart'; -import 'package:open_api/src/v3/components.dart'; -import 'package:open_api/src/v3/metadata.dart'; -import 'package:open_api/src/v3/path.dart'; -import 'package:open_api/src/v3/security.dart'; -import 'package:open_api/src/v3/server.dart'; +import 'package:open_api_forked/src/object.dart'; +import 'package:open_api_forked/src/v3/components.dart'; +import 'package:open_api_forked/src/v3/metadata.dart'; +import 'package:open_api_forked/src/v3/path.dart'; +import 'package:open_api_forked/src/v3/security.dart'; +import 'package:open_api_forked/src/v3/server.dart'; /// This is the root document object of the OpenAPI document. class APIDocument extends APIObject { diff --git a/lib/src/v3/encoding.dart b/lib/src/v3/encoding.dart index dc23926..285d98a 100644 --- a/lib/src/v3/encoding.dart +++ b/lib/src/v3/encoding.dart @@ -1,6 +1,6 @@ -import 'package:open_api/src/object.dart'; -import 'package:open_api/src/v3/header.dart'; -import 'package:open_api/src/v3/parameter.dart'; +import 'package:open_api_forked/src/object.dart'; +import 'package:open_api_forked/src/v3/header.dart'; +import 'package:open_api_forked/src/v3/parameter.dart'; /// A single encoding definition applied to a single schema property. class APIEncoding extends APIObject { diff --git a/lib/src/v3/header.dart b/lib/src/v3/header.dart index b01e846..35be320 100644 --- a/lib/src/v3/header.dart +++ b/lib/src/v3/header.dart @@ -1,6 +1,6 @@ import 'package:codable/codable.dart'; -import 'package:open_api/src/v3/parameter.dart'; -import 'package:open_api/src/v3/schema.dart'; +import 'package:open_api_forked/src/v3/parameter.dart'; +import 'package:open_api_forked/src/v3/schema.dart'; /// [APIHeader] follows the structure of the [APIParameter] with the following changes: /// diff --git a/lib/src/v3/media_type.dart b/lib/src/v3/media_type.dart index 3b0d775..72786db 100644 --- a/lib/src/v3/media_type.dart +++ b/lib/src/v3/media_type.dart @@ -1,6 +1,6 @@ -import 'package:open_api/src/object.dart'; -import 'package:open_api/src/v3/encoding.dart'; -import 'package:open_api/src/v3/schema.dart'; +import 'package:open_api_forked/src/object.dart'; +import 'package:open_api_forked/src/v3/encoding.dart'; +import 'package:open_api_forked/src/v3/schema.dart'; /// Each [APIMediaType] provides schema and examples for the media type identified by its key. class APIMediaType extends APIObject { diff --git a/lib/src/v3/metadata.dart b/lib/src/v3/metadata.dart index e5ca37d..516bfbd 100644 --- a/lib/src/v3/metadata.dart +++ b/lib/src/v3/metadata.dart @@ -1,4 +1,4 @@ -import 'package:open_api/src/object.dart'; +import 'package:open_api_forked/src/object.dart'; /// The object provides metadata about the API. /// diff --git a/lib/src/v3/operation.dart b/lib/src/v3/operation.dart index b8729dd..a021e8a 100644 --- a/lib/src/v3/operation.dart +++ b/lib/src/v3/operation.dart @@ -1,13 +1,13 @@ import 'package:codable/cast.dart' as cast; -import 'package:open_api/src/object.dart'; -import 'package:open_api/src/v3/callback.dart'; -import 'package:open_api/src/v3/parameter.dart'; -import 'package:open_api/src/v3/request_body.dart'; -import 'package:open_api/src/v3/response.dart'; -import 'package:open_api/src/v3/security.dart'; -import 'package:open_api/src/v3/path.dart'; -import 'package:open_api/src/v3/document.dart'; -import 'package:open_api/src/v3/server.dart'; +import 'package:open_api_forked/src/object.dart'; +import 'package:open_api_forked/src/v3/callback.dart'; +import 'package:open_api_forked/src/v3/parameter.dart'; +import 'package:open_api_forked/src/v3/request_body.dart'; +import 'package:open_api_forked/src/v3/response.dart'; +import 'package:open_api_forked/src/v3/security.dart'; +import 'package:open_api_forked/src/v3/path.dart'; +import 'package:open_api_forked/src/v3/document.dart'; +import 'package:open_api_forked/src/v3/server.dart'; /// Describes a single API operation on a path. class APIOperation extends APIObject { diff --git a/lib/src/v3/parameter.dart b/lib/src/v3/parameter.dart index 02bbd1f..1c2a755 100644 --- a/lib/src/v3/parameter.dart +++ b/lib/src/v3/parameter.dart @@ -1,7 +1,7 @@ -import 'package:open_api/src/object.dart'; -import 'package:open_api/src/v3/document.dart'; -import 'package:open_api/src/v3/media_type.dart'; -import 'package:open_api/src/v3/schema.dart'; +import 'package:open_api_forked/src/object.dart'; +import 'package:open_api_forked/src/v3/document.dart'; +import 'package:open_api_forked/src/v3/media_type.dart'; +import 'package:open_api_forked/src/v3/schema.dart'; /// There are four possible parameter locations specified by the in field. /// diff --git a/lib/src/v3/path.dart b/lib/src/v3/path.dart index df52e4b..0317cc6 100644 --- a/lib/src/v3/path.dart +++ b/lib/src/v3/path.dart @@ -1,6 +1,6 @@ -import 'package:open_api/src/object.dart'; -import 'package:open_api/src/v3/operation.dart'; -import 'package:open_api/src/v3/parameter.dart'; +import 'package:open_api_forked/src/object.dart'; +import 'package:open_api_forked/src/v3/operation.dart'; +import 'package:open_api_forked/src/v3/parameter.dart'; /// Describes the operations available on a single path. /// diff --git a/lib/src/v3/request_body.dart b/lib/src/v3/request_body.dart index 1f54bb5..da4b44e 100644 --- a/lib/src/v3/request_body.dart +++ b/lib/src/v3/request_body.dart @@ -1,6 +1,6 @@ -import 'package:open_api/src/object.dart'; -import 'package:open_api/src/v3/media_type.dart'; -import 'package:open_api/src/v3/schema.dart'; +import 'package:open_api_forked/src/object.dart'; +import 'package:open_api_forked/src/v3/media_type.dart'; +import 'package:open_api_forked/src/v3/schema.dart'; /// Describes a single request body. class APIRequestBody extends APIObject { diff --git a/lib/src/v3/response.dart b/lib/src/v3/response.dart index 50c9f97..cd822c0 100644 --- a/lib/src/v3/response.dart +++ b/lib/src/v3/response.dart @@ -1,7 +1,7 @@ -import 'package:open_api/src/object.dart'; -import 'package:open_api/src/v3/header.dart'; -import 'package:open_api/src/v3/media_type.dart'; -import 'package:open_api/src/v3/schema.dart'; +import 'package:open_api_forked/src/object.dart'; +import 'package:open_api_forked/src/v3/header.dart'; +import 'package:open_api_forked/src/v3/media_type.dart'; +import 'package:open_api_forked/src/v3/schema.dart'; /// Describes a single response from an API Operation, including design-time, static links to operations based on the response. class APIResponse extends APIObject { diff --git a/lib/src/v3/schema.dart b/lib/src/v3/schema.dart index e34eb0c..5240e39 100644 --- a/lib/src/v3/schema.dart +++ b/lib/src/v3/schema.dart @@ -1,6 +1,6 @@ import 'package:codable/cast.dart' as cast; -import 'package:open_api/src/object.dart'; -import 'package:open_api/src/v3/types.dart'; +import 'package:open_api_forked/src/object.dart'; +import 'package:open_api_forked/src/v3/types.dart'; enum APISchemaAdditionalPropertyPolicy { /// When [APISchemaObject] prevents properties other than those defined by [APISchemaObject.properties] from being included diff --git a/lib/src/v3/security.dart b/lib/src/v3/security.dart index 668113f..07f67f0 100644 --- a/lib/src/v3/security.dart +++ b/lib/src/v3/security.dart @@ -1,8 +1,8 @@ -import 'package:open_api/src/object.dart'; -import 'package:open_api/src/v3/components.dart'; -import 'package:open_api/src/v3/document.dart'; -import 'package:open_api/src/v3/operation.dart'; -import 'package:open_api/src/v3/parameter.dart'; +import 'package:open_api_forked/src/object.dart'; +import 'package:open_api_forked/src/v3/components.dart'; +import 'package:open_api_forked/src/v3/document.dart'; +import 'package:open_api_forked/src/v3/operation.dart'; +import 'package:open_api_forked/src/v3/parameter.dart'; enum APISecuritySchemeType { apiKey, http, oauth2, openID } @@ -264,4 +264,4 @@ class APISecurityRequirement extends APIObject { requirements[key] = req; }); } -} \ No newline at end of file +} diff --git a/lib/src/v3/server.dart b/lib/src/v3/server.dart index a7d68c2..cbc774f 100644 --- a/lib/src/v3/server.dart +++ b/lib/src/v3/server.dart @@ -1,4 +1,4 @@ -import 'package:open_api/src/object.dart'; +import 'package:open_api_forked/src/object.dart'; /// An object representing a Server. class APIServerDescription extends APIObject { diff --git a/lib/v2.dart b/lib/v2.dart index 9f65623..a5f3832 100644 --- a/lib/v2.dart +++ b/lib/v2.dart @@ -6,13 +6,13 @@ /// More dartdocs go here. library open_api_v2; -export 'package:open_api/src/v2/document.dart'; -export 'package:open_api/src/v2/header.dart'; -export 'package:open_api/src/v2/metadata.dart'; -export 'package:open_api/src/v2/operation.dart'; -export 'package:open_api/src/v2/parameter.dart'; -export 'package:open_api/src/v2/path.dart'; -export 'package:open_api/src/v2/response.dart'; -export 'package:open_api/src/v2/schema.dart'; -export 'package:open_api/src/v2/security.dart'; -export 'package:open_api/src/v2/types.dart'; +export 'package:open_api_forked/src/v2/document.dart'; +export 'package:open_api_forked/src/v2/header.dart'; +export 'package:open_api_forked/src/v2/metadata.dart'; +export 'package:open_api_forked/src/v2/operation.dart'; +export 'package:open_api_forked/src/v2/parameter.dart'; +export 'package:open_api_forked/src/v2/path.dart'; +export 'package:open_api_forked/src/v2/response.dart'; +export 'package:open_api_forked/src/v2/schema.dart'; +export 'package:open_api_forked/src/v2/security.dart'; +export 'package:open_api_forked/src/v2/types.dart'; diff --git a/lib/v3.dart b/lib/v3.dart index e958dff..68ce9d7 100644 --- a/lib/v3.dart +++ b/lib/v3.dart @@ -1,19 +1,19 @@ library open_api_v3; -export 'package:open_api/src/v3/callback.dart'; -export 'package:open_api/src/v3/components.dart'; -export 'package:open_api/src/v3/document.dart'; -export 'package:open_api/src/v3/encoding.dart'; -export 'package:open_api/src/v3/header.dart'; -export 'package:open_api/src/v3/media_type.dart'; -export 'package:open_api/src/v3/metadata.dart'; -export 'package:open_api/src/v3/operation.dart'; -export 'package:open_api/src/v3/parameter.dart'; -export 'package:open_api/src/v3/path.dart'; -export 'package:open_api/src/v3/request_body.dart'; -export 'package:open_api/src/v3/response.dart'; -export 'package:open_api/src/v3/schema.dart'; -export 'package:open_api/src/v3/security.dart'; -export 'package:open_api/src/v3/server.dart'; -export 'package:open_api/src/v3/types.dart'; -export 'package:open_api/src/object.dart'; +export 'package:open_api_forked/src/v3/callback.dart'; +export 'package:open_api_forked/src/v3/components.dart'; +export 'package:open_api_forked/src/v3/document.dart'; +export 'package:open_api_forked/src/v3/encoding.dart'; +export 'package:open_api_forked/src/v3/header.dart'; +export 'package:open_api_forked/src/v3/media_type.dart'; +export 'package:open_api_forked/src/v3/metadata.dart'; +export 'package:open_api_forked/src/v3/operation.dart'; +export 'package:open_api_forked/src/v3/parameter.dart'; +export 'package:open_api_forked/src/v3/path.dart'; +export 'package:open_api_forked/src/v3/request_body.dart'; +export 'package:open_api_forked/src/v3/response.dart'; +export 'package:open_api_forked/src/v3/schema.dart'; +export 'package:open_api_forked/src/v3/security.dart'; +export 'package:open_api_forked/src/v3/server.dart'; +export 'package:open_api_forked/src/v3/types.dart'; +export 'package:open_api_forked/src/object.dart'; diff --git a/pubspec.yaml b/pubspec.yaml index e459a45..5499a4b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ -name: open_api +name: open_api_forked description: Data structures for OpenAPI (Swagger) specification. Reads and writes JSON specifications. -version: 2.0.1 +version: 2.0.1+1 homepage: https://github.com/stablekernel/open-api-dart author: stable|kernel @@ -12,4 +12,4 @@ dependencies: codable: ^1.0.0 dev_dependencies: - test: ^1.3.0 \ No newline at end of file + test: ^1.3.0 diff --git a/test/v2_test.dart b/test/v2_test.dart index 97b300f..ec91a4c 100644 --- a/test/v2_test.dart +++ b/test/v2_test.dart @@ -1,7 +1,7 @@ // Copyright (c) 2017, joeconway. All rights reserved. Use of this source code // is governed by a BSD-style license that can be found in the LICENSE file. -import 'package:open_api/v2.dart'; +import 'package:open_api_forked/v2.dart'; import 'package:test/test.dart'; import 'dart:io'; import 'dart:convert'; diff --git a/test/v3_test.dart b/test/v3_test.dart index 5df66b0..4171048 100644 --- a/test/v3_test.dart +++ b/test/v3_test.dart @@ -1,4 +1,4 @@ -import 'package:open_api/v3.dart'; +import 'package:open_api_forked/v3.dart'; import 'package:test/test.dart'; import 'dart:io'; import 'dart:convert'; From 9cf65bff4836b788501a7432705bd9307a6f1105 Mon Sep 17 00:00:00 2001 From: AnhQuan Nguyen Date: Mon, 1 Mar 2021 00:33:07 -0800 Subject: [PATCH 05/30] nullsafety --- README.md | 4 +- lib/src/object.dart | 9 +- lib/src/v2/document.dart | 34 ++-- lib/src/v2/header.dart | 6 +- lib/src/v2/metadata.dart | 12 +- lib/src/v2/operation.dart | 10 +- lib/src/v2/parameter.dart | 27 +-- lib/src/v2/path.dart | 8 +- lib/src/v2/property.dart | 45 ++--- lib/src/v2/response.dart | 8 +- lib/src/v2/schema.dart | 26 +-- lib/src/v2/security.dart | 44 +++-- lib/src/v2/types.dart | 4 +- lib/src/v3/callback.dart | 9 +- lib/src/v3/components.dart | 92 ++++++---- lib/src/v3/document.dart | 31 ++-- lib/src/v3/encoding.dart | 37 ++-- lib/src/v3/header.dart | 2 +- lib/src/v3/media_type.dart | 8 +- lib/src/v3/metadata.dart | 40 ++--- lib/src/v3/operation.dart | 63 +++---- lib/src/v3/parameter.dart | 137 +++++++-------- lib/src/v3/path.dart | 33 +++- lib/src/v3/request_body.dart | 26 +-- lib/src/v3/response.dart | 38 ++--- lib/src/v3/schema.dart | 119 +++++++------ lib/src/v3/security.dart | 93 ++++++---- lib/src/v3/server.dart | 26 +-- lib/src/v3/types.dart | 11 +- pubspec.yaml | 8 +- test/v2_test.dart | 81 +++++---- test/v3_test.dart | 320 ++++++++++++++++++++--------------- 32 files changed, 793 insertions(+), 618 deletions(-) diff --git a/README.md b/README.md index 704cafc..9021ff7 100644 --- a/README.md +++ b/README.md @@ -6,9 +6,9 @@ Example --- ```dart -final file = new File("test/specs/kubernetes.json"); +final file = File("test/specs/kubernetes.json"); final contents = await file.readAsString(); -final doc = new APIDocument.fromJSON(contents); +final doc = APIDocument.fromJSON(contents); final output = JSON.encode(doc.asMap()); ``` diff --git a/lib/src/object.dart b/lib/src/object.dart index 22eccfa..effa9ba 100644 --- a/lib/src/object.dart +++ b/lib/src/object.dart @@ -19,9 +19,12 @@ class APIObject extends Coding { @mustCallSuper void encode(KeyedArchive object) { - final invalidKeys = extensions.keys.where((key) => !key.startsWith("x-")).map((key) => "'$key'").toList(); + final invalidKeys = extensions.keys + .where((key) => !key.startsWith("x-")) + .map((key) => "'$key'") + .toList(); if (invalidKeys.length > 0) { - throw new ArgumentError( + throw ArgumentError( "extension keys must start with 'x-'. The following keys are invalid: ${invalidKeys.join(", ")}"); } @@ -29,4 +32,4 @@ class APIObject extends Coding { object.encode(key, value); }); } -} \ No newline at end of file +} diff --git a/lib/src/v2/document.dart b/lib/src/v2/document.dart index 288cec8..5d50ebe 100644 --- a/lib/src/v2/document.dart +++ b/lib/src/v2/document.dart @@ -18,21 +18,21 @@ class APIDocument extends APIObject { } String version = "2.0"; - APIInfo info = new APIInfo(); - String host; - String basePath; + APIInfo info = APIInfo(); + String? host; + String? basePath; - List tags = []; + List tags = []; List schemes = []; List consumes = []; List produces = []; List>> security = []; - Map paths = {}; - Map responses = {}; - Map parameters = {}; - Map definitions = {}; - Map securityDefinitions = {}; + Map paths = {}; + Map responses = {}; + Map parameters = {}; + Map definitions = {}; + Map securityDefinitions = {}; Map asMap() { return KeyedArchive.archive(this, allowReferences: true); @@ -57,13 +57,15 @@ class APIDocument extends APIObject { produces = object["produces"]; security = object["security"]; - info = object.decodeObject("info", () => new APIInfo()); - tags = object.decodeObjects("tags", () => new APITag()); - paths = object.decodeObjectMap("paths", () => new APIPath()); - responses = object.decodeObjectMap("responses", () => new APIResponse()); - parameters = object.decodeObjectMap("parameters", () => new APIParameter()); - definitions = object.decodeObjectMap("definitions", () => new APISchemaObject()); - securityDefinitions = object.decodeObjectMap("securityDefinitions", () => new APISecurityScheme()); + info = object.decodeObject("info", () => APIInfo())!; + tags = object.decodeObjects("tags", () => APITag())!; + paths = object.decodeObjectMap("paths", () => APIPath())!; + responses = object.decodeObjectMap("responses", () => APIResponse())!; + parameters = object.decodeObjectMap("parameters", () => APIParameter())!; + definitions = + object.decodeObjectMap("definitions", () => APISchemaObject())!; + securityDefinitions = object.decodeObjectMap( + "securityDefinitions", () => APISecurityScheme())!; } void encode(KeyedArchive object) { diff --git a/lib/src/v2/header.dart b/lib/src/v2/header.dart index bde5d29..4aefd79 100644 --- a/lib/src/v2/header.dart +++ b/lib/src/v2/header.dart @@ -6,14 +6,14 @@ import 'package:open_api/src/v2/types.dart'; class APIHeader extends APIProperty { APIHeader(); - String description; - APIProperty items; + String? description; + APIProperty? items; void decode(KeyedArchive json) { super.decode(json); description = json.decode("description"); if (type == APIType.array) { - items = json.decodeObject("items", () => new APIProperty()); + items = json.decodeObject("items", () => APIProperty()); } } diff --git a/lib/src/v2/metadata.dart b/lib/src/v2/metadata.dart index eca70b6..c9f0fac 100644 --- a/lib/src/v2/metadata.dart +++ b/lib/src/v2/metadata.dart @@ -9,8 +9,8 @@ class APIInfo extends APIObject { String description = "Description"; String version = "1.0"; String termsOfServiceURL = ""; - APIContact contact = new APIContact(); - APILicense license = new APILicense(); + APIContact contact = APIContact(); + APILicense license = APILicense(); void decode(KeyedArchive object) { super.decode(object); @@ -18,8 +18,8 @@ class APIInfo extends APIObject { title = object.decode("title"); description = object.decode("description"); termsOfServiceURL = object.decode("termsOfService"); - contact = object.decodeObject("contact", () => new APIContact()); - license = object.decodeObject("license", () => new APILicense()); + contact = object.decodeObject("contact", () => APIContact())!; + license = object.decodeObject("license", () => APILicense())!; version = object.decode("version"); } @@ -92,8 +92,8 @@ class APITag extends APIObject { description = object.decode("description"); } - String name; - String description; + String? name; + String? description; void encode(KeyedArchive object) { super.encode(object); diff --git a/lib/src/v2/operation.dart b/lib/src/v2/operation.dart index 4e7c799..2d64a6b 100644 --- a/lib/src/v2/operation.dart +++ b/lib/src/v2/operation.dart @@ -18,16 +18,16 @@ class APIOperation extends APIObject { String summary = ""; String description = ""; - String id; + String? id; bool deprecated = false; List tags = []; List schemes = []; List consumes = []; List produces = []; - List parameters = []; + List parameters = []; List>> security = []; - Map responses = {}; + Map responses = {}; void decode(KeyedArchive object) { super.decode(object); @@ -39,8 +39,8 @@ class APIOperation extends APIObject { consumes = object.decode("consumes"); produces = object.decode("produces"); deprecated = object.decode("deprecated") ?? false; - parameters = object.decodeObjects("parameters", () => new APIParameter()); - responses = object.decodeObjectMap("responses", () => new APIResponse()); + parameters = object.decodeObjects("parameters", () => APIParameter())!; + responses = object.decodeObjectMap("responses", () => APIResponse())!; schemes = object.decode("schemes"); security = object.decode("security"); } diff --git a/lib/src/v2/parameter.dart b/lib/src/v2/parameter.dart index da11d3f..0fa22e7 100644 --- a/lib/src/v2/parameter.dart +++ b/lib/src/v2/parameter.dart @@ -7,7 +7,7 @@ import 'package:open_api/src/v2/types.dart'; enum APIParameterLocation { query, header, path, formData, body } class APIParameterLocationCodec { - static APIParameterLocation decode(String location) { + static APIParameterLocation? decode(String location) { switch (location) { case "query": return APIParameterLocation.query; @@ -19,12 +19,12 @@ class APIParameterLocationCodec { return APIParameterLocation.formData; case "body": return APIParameterLocation.body; + default: + return null; } - - return null; } - static String encode(APIParameterLocation location) { + static String? encode(APIParameterLocation location) { switch (location) { case APIParameterLocation.query: return "query"; @@ -36,8 +36,9 @@ class APIParameterLocationCodec { return "formData"; case APIParameterLocation.body: return "body"; + default: + return null; } - return null; } } @@ -45,17 +46,17 @@ class APIParameterLocationCodec { class APIParameter extends APIProperty { APIParameter(); - String name; - String description; + String? name; + String? description; bool required = false; - APIParameterLocation location; + APIParameterLocation? location; // Valid if location is body. - APISchemaObject schema; + APISchemaObject? schema; // Valid if location is not body. bool allowEmptyValue = false; - APIProperty items; + APIProperty? items; void decode(KeyedArchive json) { name = json.decode("name"); @@ -68,12 +69,12 @@ class APIParameter extends APIProperty { } if (location == APIParameterLocation.body) { - schema = json.decodeObject("schema", () => new APISchemaObject()); + schema = json.decodeObject("schema", () => APISchemaObject()); } else { super.decode(json); allowEmptyValue = json.decode("allowEmptyValue") ?? false; if (type == APIType.array) { - items = json.decodeObject("items", () => new APIProperty()); + items = json.decodeObject("items", () => APIProperty()); } } } @@ -81,7 +82,7 @@ class APIParameter extends APIProperty { void encode(KeyedArchive json) { json.encode("name", name); json.encode("description", description); - json.encode("in", APIParameterLocationCodec.encode(location)); + json.encode("in", APIParameterLocationCodec.encode(location!)); json.encode("required", required); if (location == APIParameterLocation.body) { diff --git a/lib/src/v2/path.dart b/lib/src/v2/path.dart index 19dd817..535cc34 100644 --- a/lib/src/v2/path.dart +++ b/lib/src/v2/path.dart @@ -6,8 +6,8 @@ import 'package:open_api/src/v2/parameter.dart'; class APIPath extends APIObject { APIPath(); - List parameters = []; - Map operations = {}; + List parameters = []; + Map operations = {}; void decode(KeyedArchive object) { super.decode(object); @@ -16,9 +16,9 @@ class APIPath extends APIObject { if (k == r"$ref") { // todo: reference } else if (k == "parameters") { - parameters = object.decodeObjects(k, () => new APIParameter()); + parameters = object.decodeObjects(k, () => APIParameter())!; } else { - operations[k] = object.decodeObject(k, () => new APIOperation()); + operations[k] = object.decodeObject(k, () => APIOperation()); } }); } diff --git a/lib/src/v2/property.dart b/lib/src/v2/property.dart index a6a8e4c..4d87fe9 100644 --- a/lib/src/v2/property.dart +++ b/lib/src/v2/property.dart @@ -12,7 +12,7 @@ enum APISchemaRepresentation { enum APICollectionFormat { csv, ssv, tsv, pipes } class APICollectionFormatCodec { - static APICollectionFormat decode(String location) { + static APICollectionFormat? decode(String location) { switch (location) { case "csv": return APICollectionFormat.csv; @@ -22,12 +22,12 @@ class APICollectionFormatCodec { return APICollectionFormat.tsv; case "pipes": return APICollectionFormat.pipes; + default: + return null; } - - return null; } - static String encode(APICollectionFormat location) { + static String? encode(APICollectionFormat location) { switch (location) { case APICollectionFormat.csv: return "csv"; @@ -37,29 +37,30 @@ class APICollectionFormatCodec { return "tsv"; case APICollectionFormat.pipes: return "pipes"; + default: + return null; } - return null; } } class APIProperty extends APIObject { - APIType type; - String format; + APIType? type; + String? format; - APICollectionFormat collectionFormat; + APICollectionFormat? collectionFormat; dynamic defaultValue; - num maximum; - bool exclusiveMaximum; - num minimum; - bool exclusiveMinimum; - int maxLength; - int minLength; - String pattern; - int maxItems; - int minItems; - bool uniqueItems; - num multipleOf; - List enumerated; + num? maximum; + bool? exclusiveMaximum; + num? minimum; + bool? exclusiveMinimum; + int? maxLength; + int? minLength; + String? pattern; + int? maxItems; + int? minItems; + bool? uniqueItems; + num? multipleOf; + List? enumerated; APISchemaRepresentation get representation { if (type == APIType.array) { @@ -96,10 +97,10 @@ class APIProperty extends APIObject { void encode(KeyedArchive object) { super.encode(object); - object.encode("type", APITypeCodec.encode(type)); + object.encode("type", APITypeCodec.encode(type!)); object.encode("format", format); object.encode( - "collectionFormat", APICollectionFormatCodec.encode(collectionFormat)); + "collectionFormat", APICollectionFormatCodec.encode(collectionFormat!)); object.encode("default", defaultValue); object.encode("maximum", maximum); object.encode("exclusiveMaximum", exclusiveMaximum); diff --git a/lib/src/v2/response.dart b/lib/src/v2/response.dart index 20063e5..161f074 100644 --- a/lib/src/v2/response.dart +++ b/lib/src/v2/response.dart @@ -7,15 +7,15 @@ class APIResponse extends APIObject { APIResponse(); String description = ""; - APISchemaObject schema; - Map headers = {}; + APISchemaObject? schema; + Map headers = {}; void decode(KeyedArchive object) { super.decode(object); description = object.decode("description"); - schema = object.decodeObject("schema", () => new APISchemaObject()); - headers = object.decodeObjectMap("headers", () => new APIHeader()); + schema = object.decodeObject("schema", () => APISchemaObject()); + headers = object.decodeObjectMap("headers", () => APIHeader())!; } void encode(KeyedArchive object) { diff --git a/lib/src/v2/schema.dart b/lib/src/v2/schema.dart index ab7837e..9f1dec6 100644 --- a/lib/src/v2/schema.dart +++ b/lib/src/v2/schema.dart @@ -6,20 +6,20 @@ import 'package:open_api/src/v2/property.dart'; class APISchemaObject extends APIProperty { APISchemaObject(); - String title; - String description; - String example; - List required = []; + String? title; + String? description; + String? example; + List isRequired = []; bool readOnly = false; /// Valid when type == array - APISchemaObject items; + APISchemaObject? items; /// Valid when type == null - Map properties; + Map? properties; /// Valid when type == object - APISchemaObject additionalProperties; + APISchemaObject? additionalProperties; @override APISchemaRepresentation get representation { @@ -38,14 +38,14 @@ class APISchemaObject extends APIProperty { title = json.decode("title"); description = json.decode("description"); - required = json.decode("required"); + isRequired = json.decode("required"); example = json.decode("example"); readOnly = json.decode("readOnly") ?? false; - items = json.decodeObject("items", () => new APISchemaObject()); - additionalProperties = json.decodeObject("additionalProperties", () => new APISchemaObject()); - properties = - json.decodeObjectMap("properties", () => new APISchemaObject()); + items = json.decodeObject("items", () => APISchemaObject()); + additionalProperties = + json.decodeObject("additionalProperties", () => APISchemaObject()); + properties = json.decodeObjectMap("properties", () => APISchemaObject()); } void encode(KeyedArchive json) { @@ -53,7 +53,7 @@ class APISchemaObject extends APIProperty { json.encode("title", title); json.encode("description", description); - json.encode("required", required); + json.encode("required", isRequired); json.encode("example", example); json.encode("readOnly", readOnly); diff --git a/lib/src/v2/security.dart b/lib/src/v2/security.dart index a7575c0..45cad67 100644 --- a/lib/src/v2/security.dart +++ b/lib/src/v2/security.dart @@ -3,10 +3,15 @@ import 'package:open_api/src/object.dart'; import 'package:open_api/src/v2/parameter.dart'; /// Represents a OAuth 2.0 security scheme flow in the OpenAPI specification. -enum APISecuritySchemeFlow { implicit, password, application, authorizationCode } +enum APISecuritySchemeFlow { + implicit, + password, + application, + authorizationCode +} class APISecuritySchemeFlowCodec { - static APISecuritySchemeFlow decode(String flow) { + static APISecuritySchemeFlow? decode(String flow) { switch (flow) { case "accessCode": return APISecuritySchemeFlow.authorizationCode; @@ -16,11 +21,12 @@ class APISecuritySchemeFlowCodec { return APISecuritySchemeFlow.implicit; case "application": return APISecuritySchemeFlow.application; + default: + return null; } - return null; } - static String encode(APISecuritySchemeFlow flow) { + static String? encode(APISecuritySchemeFlow flow) { switch (flow) { case APISecuritySchemeFlow.authorizationCode: return "accessCode"; @@ -30,8 +36,9 @@ class APISecuritySchemeFlowCodec { return "implicit"; case APISecuritySchemeFlow.application: return "application"; + default: + return null; } - return null; } } @@ -47,22 +54,23 @@ class APISecurityScheme extends APIObject { type = "apiKey"; } - APISecurityScheme.oauth2(this.oauthFlow, {this.authorizationURL, this.tokenURL, this.scopes: const {}}) { + APISecurityScheme.oauth2(this.oauthFlow, + {this.authorizationURL, this.tokenURL, this.scopes: const {}}) { type = "oauth2"; } - String type; - String description; + late String type; + String? description; // API Key - String apiKeyName; - APIParameterLocation apiKeyLocation; + String? apiKeyName; + APIParameterLocation? apiKeyLocation; // Oauth2 - APISecuritySchemeFlow oauthFlow; - String authorizationURL; - String tokenURL; - Map scopes; + APISecuritySchemeFlow? oauthFlow; + String? authorizationURL; + String? tokenURL; + Map? scopes; bool get isOAuth2 { return type == "oauth2"; @@ -70,7 +78,7 @@ class APISecurityScheme extends APIObject { @override Map get castMap => - {"scopes": cast.Map(cast.String, cast.String)}; + {"scopes": cast.Map(cast.String, cast.String)}; void decode(KeyedArchive object) { super.decode(object); @@ -83,7 +91,7 @@ class APISecurityScheme extends APIObject { oauthFlow = APISecuritySchemeFlowCodec.decode(object.decode("flow")); authorizationURL = object.decode("authorizationUrl"); tokenURL = object.decode("tokenUrl"); - scopes = new Map.from(object.decode("scopes")); + scopes = Map.from(object.decode("scopes")); } else if (type == "apiKey") { apiKeyName = object.decode("name"); apiKeyLocation = APIParameterLocationCodec.decode(object.decode("in")); @@ -100,9 +108,9 @@ class APISecurityScheme extends APIObject { /* nothing to do */ } else if (type == "apiKey") { object.encode("name", apiKeyName); - object.encode("in", APIParameterLocationCodec.encode(apiKeyLocation)); + object.encode("in", APIParameterLocationCodec.encode(apiKeyLocation!)); } else if (type == "oauth2") { - object.encode("flow", APISecuritySchemeFlowCodec.encode(oauthFlow)); + object.encode("flow", APISecuritySchemeFlowCodec.encode(oauthFlow!)); object.encode("authorizationUrl", authorizationURL); object.encode("tokenUrl", tokenURL); diff --git a/lib/src/v2/types.dart b/lib/src/v2/types.dart index af9ae8f..6c22a18 100644 --- a/lib/src/v2/types.dart +++ b/lib/src/v2/types.dart @@ -1,7 +1,7 @@ enum APIType { string, number, integer, boolean, array, file, object } class APITypeCodec { - static APIType decode(String type) { + static APIType? decode(String type) { switch (type) { case "string": return APIType.string; @@ -21,7 +21,7 @@ class APITypeCodec { return null; } - static String encode(APIType type) { + static String? encode(APIType type) { switch (type) { case APIType.string: return "string"; diff --git a/lib/src/v3/callback.dart b/lib/src/v3/callback.dart index 9c3c347..f76d59c 100644 --- a/lib/src/v3/callback.dart +++ b/lib/src/v3/callback.dart @@ -11,7 +11,7 @@ class APICallback extends APIObject { /// Callback paths. /// /// The key that identifies the [APIPath] is a runtime expression that can be evaluated in the context of a runtime HTTP request/response to identify the URL to be used for the callback request. A simple example might be $request.body#/url. - Map paths; + Map? paths; void decode(KeyedArchive object) { super.decode(object); @@ -19,14 +19,15 @@ class APICallback extends APIObject { paths = {}; object.forEach((key, dynamic value) { if (value is! KeyedArchive) { - throw new ArgumentError("Invalid specification. Callback contains non-object value."); + throw ArgumentError( + "Invalid specification. Callback contains non-object value."); } - paths[key] = value.decode(key, inflate: () => new APIPath()); + paths![key] = value.decodeObject(key, () => APIPath())!; }); } void encode(KeyedArchive object) { super.encode(object); - throw new StateError("APICallback.encode: not yet implemented."); + throw StateError("APICallback.encode: not yet implemented."); } } diff --git a/lib/src/v3/components.dart b/lib/src/v3/components.dart index ac45d07..fbc592e 100644 --- a/lib/src/v3/components.dart +++ b/lib/src/v3/components.dart @@ -15,85 +15,103 @@ class APIComponents extends APIObject { APIComponents.empty(); - /// An object to hold reusable [APISchemaObject]. - Map schemas = {}; + /// An object to hold reusable [APISchemaObject?]. + Map? schemas = {}; - /// An object to hold reusable [APIResponse]. - Map responses = {}; + /// An object to hold reusable [APIResponse?]. + Map? responses = {}; - /// An object to hold reusable [APIParameter]. - Map parameters = {}; + /// An object to hold reusable [APIParameter?]. + Map? parameters = {}; //Map examples = {}; - /// An object to hold reusable [APIRequestBody]. - Map requestBodies = {}; + /// An object to hold reusable [APIRequestBody?]. + Map? requestBodies = {}; /// An object to hold reusable [APIHeader]. - Map headers = {}; + Map? headers = {}; - /// An object to hold reusable [APISecurityScheme]. - Map securitySchemes = {}; + /// An object to hold reusable [APISecurityScheme?]. + Map? securitySchemes = {}; //Map links = {}; - /// An object to hold reusable [APICallback]. - Map callbacks = {}; + /// An object to hold reusable [APICallback?]. + Map? callbacks = {}; /// Returns a component definition for [uri]. /// /// Construct [uri] as a path, e.g. `Uri(path: /components/schemas/name)`. - APIObject resolveUri(Uri uri) { + APIObject? resolveUri(Uri uri) { final segments = uri.pathSegments; if (segments.length != 3) { - throw new ArgumentError("Invalid reference URI. Must be a path URI of the form: '/components//'"); + throw ArgumentError( + "Invalid reference URI. Must be a path URI of the form: '/components//'"); } if (segments.first != "components") { - throw new ArgumentError("Invalid reference URI: does not begin with /components/"); + throw ArgumentError( + "Invalid reference URI: does not begin with /components/"); } var namedMap = null; switch (segments[1]) { - case "schemas": namedMap = schemas; break; - case "responses": namedMap = responses; break; - case "parameters": namedMap = parameters; break; - case "requestBodies": namedMap = requestBodies; break; - case "headers": namedMap = headers; break; - case "securitySchemes": namedMap = securitySchemes; break; - case "callbacks": namedMap = callbacks; break; + case "schemas": + namedMap = schemas; + break; + case "responses": + namedMap = responses; + break; + case "parameters": + namedMap = parameters; + break; + case "requestBodies": + namedMap = requestBodies; + break; + case "headers": + namedMap = headers; + break; + case "securitySchemes": + namedMap = securitySchemes; + break; + case "callbacks": + namedMap = callbacks; + break; } if (namedMap == null) { - throw new ArgumentError("Invalid reference URI: component type '${segments[1]}' does not exist."); + throw ArgumentError( + "Invalid reference URI: component type '${segments[1]}' does not exist."); } return namedMap[segments.last]; } - T resolve(T refObject) { + T? resolve(T refObject) { if (refObject.referenceURI == null) { - throw new ArgumentError("APIObject is not a reference to a component."); + throw ArgumentError("APIObject is not a reference to a component."); } - return resolveUri(refObject.referenceURI); + return resolveUri(refObject.referenceURI!) as T?; } void decode(KeyedArchive object) { super.decode(object); - schemas = object.decodeObjectMap("schemas", () => new APISchemaObject()); - responses = object.decodeObjectMap("responses", () => new APIResponse.empty()); - parameters = object.decodeObjectMap("parameters", () => new APIParameter.empty()); -// examples = object.decodeObjectMap("examples", () => new APIExample()); + schemas = object.decodeObjectMap("schemas", () => APISchemaObject())!; + responses = object.decodeObjectMap("responses", () => APIResponse.empty()); + parameters = + object.decodeObjectMap("parameters", () => APIParameter.empty()); +// examples = object.decodeObjectMap("examples", () => APIExample()); requestBodies = - object.decodeObjectMap("requestBodies", () => new APIRequestBody.empty()); - headers = object.decodeObjectMap("headers", () => new APIHeader()); + object.decodeObjectMap("requestBodies", () => APIRequestBody.empty()); + headers = object.decodeObjectMap("headers", () => APIHeader()); - securitySchemes = object.decodeObjectMap( - "securitySchemes", () => new APISecurityScheme()); -// links = object.decodeObjectMap("links", () => new APILink()); - callbacks = object.decodeObjectMap("callbacks", () => new APICallback()); + securitySchemes = + object.decodeObjectMap("securitySchemes", () => APISecurityScheme()); +// links = object.decodeObjectMap("links", () => APILink()); + callbacks = object.decodeObjectMap("callbacks", () => APICallback()); } void encode(KeyedArchive object) { diff --git a/lib/src/v3/document.dart b/lib/src/v3/document.dart index 3a3fa69..2bab4a9 100644 --- a/lib/src/v3/document.dart +++ b/lib/src/v3/document.dart @@ -18,35 +18,35 @@ class APIDocument extends APIObject { /// This string MUST be the semantic version number of the OpenAPI Specification version that the OpenAPI document uses. /// /// REQUIRED. The openapi field SHOULD be used by tooling specifications and clients to interpret the OpenAPI document. This is not related to the API info.version string. - String version = "3.0.0"; + String? version = "3.0.0"; /// Provides metadata about the API. /// /// REQUIRED. The metadata MAY be used by tooling as required. - APIInfo info; + APIInfo? info; /// An array of [APIServerDescription], which provide connectivity information to a target server. /// /// If the servers property is not provided, or is an empty array, the default value would be a [APIServerDescription] with a url value of /. - List servers; + List? servers; /// The available paths and operations for the API. /// /// REQUIRED. - Map paths; + Map? paths; /// An element to hold various schemas for the specification. - APIComponents components; + APIComponents? components; /// A declaration of which security mechanisms can be used across the API. /// /// The list of values includes alternative security requirement objects that can be used. Only one of the security requirement objects need to be satisfied to authorize a request. Individual operations can override this definition. - List security; + List? security; /// A list of tags used by the specification with additional metadata. /// /// The order of the tags can be used to reflect on their order by the parsing tools. Not all tags that are used by the Operation Object must be declared. The tags that are not declared MAY be organized randomly or based on the tools' logic. Each tag name in the list MUST be unique. - List tags; + List? tags; Map asMap() { return KeyedArchive.archive(this, allowReferences: true); @@ -56,22 +56,23 @@ class APIDocument extends APIObject { super.decode(object); version = object.decode("openapi"); - info = object.decodeObject("info", () => new APIInfo.empty()); - servers = object.decodeObjects("servers", () => new APIServerDescription.empty()); - paths = object.decodeObjectMap("paths", () => new APIPath()); - components = - object.decodeObject("components", () => new APIComponents()); + info = object.decodeObject("info", () => APIInfo.empty())!; + servers = + object.decodeObjects("servers", () => APIServerDescription.empty()); + paths = object.decodeObjectMap("paths", () => APIPath()); + components = object.decodeObject("components", () => APIComponents()); security = object.decode("security"); - tags = object.decodeObjects("tags", () => new APITag.empty()); + tags = object.decodeObjects("tags", () => APITag.empty()); } void encode(KeyedArchive object) { super.encode(object); if (version == null || info == null || paths == null) { - throw new ArgumentError("APIDocument must have non-null values for: 'version', 'info', 'paths'."); + throw ArgumentError( + "APIDocument must have non-null values for: 'version', 'info', 'paths'."); } - + object.encode("openapi", version); object.encodeObject("info", info); object.encodeObjects("servers", servers); diff --git a/lib/src/v3/encoding.dart b/lib/src/v3/encoding.dart index dc23926..ad3c2f8 100644 --- a/lib/src/v3/encoding.dart +++ b/lib/src/v3/encoding.dart @@ -4,9 +4,14 @@ import 'package:open_api/src/v3/parameter.dart'; /// A single encoding definition applied to a single schema property. class APIEncoding extends APIObject { - APIEncoding({this.contentType, this.headers, this.style, bool allowReserved, bool explode}) { - this.allowReserved = allowReserved; - this.explode = explode; + APIEncoding( + {this.contentType, + this.headers, + this.style, + bool? allowReserved, + bool? explode}) { + this.allowReserved = allowReserved ?? false; + this.explode = explode ?? false; } APIEncoding.empty(); @@ -14,37 +19,43 @@ class APIEncoding extends APIObject { /// The Content-Type for encoding a specific property. /// /// Default value depends on the property type: for string with format being binary – application/octet-stream; for other primitive types – text/plain; for object - application/json; for array – the default is defined based on the inner type. The value can be a specific media type (e.g. application/json), a wildcard media type (e.g. image/*), or a comma-separated list of the two types. - String contentType; + String? contentType; /// A map allowing additional information to be provided as headers, for example Content-Disposition. /// /// Content-Type is described separately and SHALL be ignored in this section. This property SHALL be ignored if the request body media type is not a multipart. - Map headers; + Map? headers; /// Determines whether the parameter value SHOULD allow reserved characters, as defined by RFC3986 :/?#[]@!$&'()*+,;= to be included without percent-encoding. /// /// The default value is false. This property SHALL be ignored if the request body media type is not application/x-www-form-urlencoded. - bool get allowReserved => _allowReserved ?? false; - set allowReserved(bool f) { _allowReserved = f; } - bool _allowReserved; + bool get allowReserved => _allowReserved; + set allowReserved(bool f) { + _allowReserved = f; + } + + bool _allowReserved = false; /// When this is true, property values of type array or object generate separate parameters for each value of the array, or key-value-pair of the map. /// /// For other types of properties this property has no effect. When style is form, the default value is true. For all other styles, the default value is false. This property SHALL be ignored if the request body media type is not application/x-www-form-urlencoded. - bool get explode => _explode ?? false; - set explode(bool f) { _explode = f; } - bool _explode; + bool get explode => _explode; + set explode(bool f) { + _explode = f; + } + + bool _explode = false; /// Describes how a specific property value will be serialized depending on its type. /// /// See [APIParameter] for details on the style property. The behavior follows the same values as query parameters, including default values. This property SHALL be ignored if the request body media type is not application/x-www-form-urlencoded. - String style; + String? style; void decode(KeyedArchive object) { super.decode(object); contentType = object.decode("contentType"); - headers = object.decodeObjectMap("headers", () => new APIHeader()); + headers = object.decodeObjectMap("headers", () => APIHeader()); _allowReserved = object.decode("allowReserved"); _explode = object.decode("explode"); style = object.decode("style"); diff --git a/lib/src/v3/header.dart b/lib/src/v3/header.dart index b01e846..c727d46 100644 --- a/lib/src/v3/header.dart +++ b/lib/src/v3/header.dart @@ -8,7 +8,7 @@ import 'package:open_api/src/v3/schema.dart'; /// in MUST NOT be specified, it is implicitly in header. /// All traits that are affected by the location MUST be applicable to a location of header (for example, style). class APIHeader extends APIParameter { - APIHeader({APISchemaObject schema}) : super.header(null, schema: schema); + APIHeader({APISchemaObject? schema}) : super.header(null, schema: schema); APIHeader.empty() : super.header(null); @override diff --git a/lib/src/v3/media_type.dart b/lib/src/v3/media_type.dart index 3b0d775..d379cba 100644 --- a/lib/src/v3/media_type.dart +++ b/lib/src/v3/media_type.dart @@ -8,18 +8,18 @@ class APIMediaType extends APIObject { APIMediaType.empty(); /// The schema defining the type used for the request body. - APISchemaObject schema; + APISchemaObject? schema; /// A map between a property name and its encoding information. /// /// The key, being the property name, MUST exist in the schema as a property. The encoding object SHALL only apply to requestBody objects when the media type is multipart or application/x-www-form-urlencoded. - Map encoding; + Map? encoding; void decode(KeyedArchive object) { super.decode(object); - schema = object.decodeObject("schema", () => new APISchemaObject()); - encoding = object.decodeObjectMap("encoding", () => new APIEncoding()); + schema = object.decodeObject("schema", () => APISchemaObject()); + encoding = object.decodeObjectMap("encoding", () => APIEncoding()); } void encode(KeyedArchive object) { diff --git a/lib/src/v3/metadata.dart b/lib/src/v3/metadata.dart index e5ca37d..206d822 100644 --- a/lib/src/v3/metadata.dart +++ b/lib/src/v3/metadata.dart @@ -7,33 +7,34 @@ class APIInfo extends APIObject { APIInfo.empty(); /// Creates empty metadata for specification. - APIInfo(this.title, this.version, {this.description, this.termsOfServiceURL, this.license, this.contact}); + APIInfo(this.title, this.version, + {this.description, this.termsOfServiceURL, this.license, this.contact}); /// The title of the application. /// /// REQUIRED. - String title; + String? title; /// A short description of the application. /// /// CommonMark syntax MAY be used for rich text representation. - String description; + String? description; /// The version of the OpenAPI document (which is distinct from the OpenAPI Specification version or the API implementation version). /// /// REQUIRED. - String version; + String? version; /// A URL to the Terms of Service for the API. /// /// MUST be in the format of a URL. - Uri termsOfServiceURL; + Uri? termsOfServiceURL; /// The contact information for the exposed API. - APIContact contact; + APIContact? contact; /// The license information for the exposed API. - APILicense license; + APILicense? license; void decode(KeyedArchive object) { super.decode(object); @@ -41,8 +42,8 @@ class APIInfo extends APIObject { title = object.decode("title"); description = object.decode("description"); termsOfServiceURL = object.decode("termsOfService"); - contact = object.decodeObject("contact", () => new APIContact()); - license = object.decodeObject("license", () => new APILicense.empty()); + contact = object.decodeObject("contact", () => APIContact()); + license = object.decodeObject("license", () => APILicense.empty()); version = object.decode("version"); } @@ -50,7 +51,8 @@ class APIInfo extends APIObject { super.encode(object); if (title == null || version == null) { - throw new ArgumentError("APIInfo must have non-null values for: 'title', 'version'."); + throw ArgumentError( + "APIInfo must have non-null values for: 'title', 'version'."); } object.encode("title", title); @@ -68,17 +70,17 @@ class APIContact extends APIObject { APIContact.empty(); /// The identifying name of the contact person/organization. - String name; + String? name; /// The URL pointing to the contact information. /// /// MUST be in the format of a URL. - Uri url; + Uri? url; /// The email address of the contact person/organization. /// /// MUST be in the format of an email address. - String email; + String? email; void decode(KeyedArchive object) { super.decode(object); @@ -105,12 +107,12 @@ class APILicense extends APIObject { /// The license name used for the API. /// /// REQUIRED. - String name; + String? name; /// A URL to the license used for the API. /// /// MUST be in the format of a URL. - Uri url; + Uri? url; void decode(KeyedArchive object) { super.decode(object); @@ -123,7 +125,7 @@ class APILicense extends APIObject { super.encode(object); if (name == null) { - throw new ArgumentError("APILicense must have non-null values for: 'name'."); + throw ArgumentError("APILicense must have non-null values for: 'name'."); } object.encode("name", name); @@ -142,12 +144,12 @@ class APITag extends APIObject { /// The name of the tag. /// /// REQUIRED. - String name; + String? name; /// A short description for the tag. /// /// CommonMark syntax MAY be used for rich text representation. - String description; + String? description; void decode(KeyedArchive object) { super.decode(object); @@ -160,7 +162,7 @@ class APITag extends APIObject { super.encode(object); if (name == null) { - throw new ArgumentError("APITag must have non-null values for: 'name'."); + throw ArgumentError("APITag must have non-null values for: 'name'."); } object.encode("name", name); object.encode("description", description); diff --git a/lib/src/v3/operation.dart b/lib/src/v3/operation.dart index b8729dd..455ccbb 100644 --- a/lib/src/v3/operation.dart +++ b/lib/src/v3/operation.dart @@ -21,62 +21,62 @@ class APIOperation extends APIObject { this.security, this.requestBody, this.callbacks, - bool deprecated}) { - isDeprecated = deprecated; + bool? deprecated}) { + isDeprecated = deprecated ?? false; } /// A list of tags for API documentation control. /// /// Tags can be used for logical grouping of operations by resources or any other qualifier. - List tags; + List? tags; /// A short summary of what the operation does. - String summary; + String? summary; /// A verbose explanation of the operation behavior. /// /// CommonMark syntax MAY be used for rich text representation. - String description; + String? description; /// Unique string used to identify the operation. /// /// The id MUST be unique among all operations described in the API. Tools and libraries MAY use the operationId to uniquely identify an operation, therefore, it is RECOMMENDED to follow common programming naming conventions. - String id; + String? id; /// A list of parameters that are applicable for this operation. /// - /// If a parameter is already defined at the Path Item, the new definition will override it but can never remove it. The list MUST NOT include duplicated parameters. A unique parameter is defined by a combination of a name and location. The list can use the Reference Object to link to parameters that are defined at the OpenAPI Object's components/parameters. - List parameters; + /// If a parameter is already defined at the Path Item, the definition will override it but can never remove it. The list MUST NOT include duplicated parameters. A unique parameter is defined by a combination of a name and location. The list can use the Reference Object to link to parameters that are defined at the OpenAPI Object's components/parameters. + List? parameters; /// A declaration of which security mechanisms can be used for this operation. /// /// The list of values includes alternative security requirement objects that can be used. Only one of the security requirement objects need to be satisfied to authorize a request. This definition overrides any declared top-level security. To remove a top-level security declaration, an empty array can be used. - List security; + List? security; /// The request body applicable for this operation. /// /// The requestBody is only supported in HTTP methods where the HTTP 1.1 specification RFC7231 has explicitly defined semantics for request bodies. In other cases where the HTTP spec is vague, requestBody SHALL be ignored by consumers. - APIRequestBody requestBody; + APIRequestBody? requestBody; /// The list of possible responses as they are returned from executing this operation. /// /// REQUIRED. - Map responses; + Map? responses; /// A map of possible out-of band callbacks related to the parent operation. /// /// The key is a unique identifier for the [APICallback]. Each value in the map is a [APICallback] that describes a request that may be initiated by the API provider and the expected responses. The key value used to identify the callback object is an expression, evaluated at runtime, that identifies a URL to use for the callback operation. - Map callbacks; + Map? callbacks; /// An alternative server array to service this operation. /// /// If an alternative server object is specified at the [APIPath] or [APIDocument] level, it will be overridden by this value. - List servers; + List? servers; /// Declares this operation to be deprecated. /// /// Consumers SHOULD refrain from usage of the declared operation. Default value is false. - bool get isDeprecated => _deprecated ?? false; + bool get isDeprecated => _deprecated; set isDeprecated(bool f) { _deprecated = f; @@ -85,7 +85,8 @@ class APIOperation extends APIObject { bool _deprecated = false; /// Returns the parameter named [name] or null if it doesn't exist. - APIParameter parameterNamed(String name) => parameters?.firstWhere((p) => p.name == name, orElse: () => null); + APIParameter? parameterNamed(String name) => + parameters?.firstWhere((p) => p?.name == name, orElse: () => null); /// Adds [parameter] to [parameters]. /// @@ -93,7 +94,7 @@ class APIOperation extends APIObject { /// Otherwise, [parameter] is added to [parameters]. void addParameter(APIParameter parameter) { parameters ??= []; - parameters.add(parameter); + parameters!.add(parameter); } /// Adds [requirement] to [security]. @@ -103,7 +104,7 @@ class APIOperation extends APIObject { void addSecurityRequirement(APISecurityRequirement requirement) { security ??= []; - security.add(requirement); + security!.add(requirement); } /// Adds [response] to [responses], merging schemas if necessary. @@ -118,22 +119,22 @@ class APIOperation extends APIObject { final key = "$statusCode"; - final existingResponse = responses[key]; + final existingResponse = responses![key]; if (existingResponse == null) { - responses[key] = response; + responses![key] = response; return; } - existingResponse.description = "${existingResponse.description ?? ""}\n${response.description}"; + existingResponse.description = + "${existingResponse.description ?? ""}\n${response.description}"; response.headers?.forEach((name, header) { existingResponse.addHeader(name, header); }); response.content?.forEach((contentType, mediaType) { - existingResponse.addContent(contentType, mediaType.schema); + existingResponse.addContent(contentType, mediaType?.schema); }); } - @override Map get castMap => {"tags": cast.List(cast.String)}; @@ -144,20 +145,24 @@ class APIOperation extends APIObject { summary = object.decode("summary"); description = object.decode("description"); id = object.decode("operationId"); - parameters = object.decodeObjects("parameters", () => new APIParameter.empty()); - requestBody = object.decodeObject("requestBody", () => new APIRequestBody.empty()); - responses = object.decodeObjectMap("responses", () => new APIResponse.empty()); - callbacks = object.decodeObjectMap("callbacks", () => new APICallback()); + parameters = object.decodeObjects("parameters", () => APIParameter.empty()); + requestBody = + object.decodeObject("requestBody", () => APIRequestBody.empty()); + responses = object.decodeObjectMap("responses", () => APIResponse.empty()); + callbacks = object.decodeObjectMap("callbacks", () => APICallback()); _deprecated = object.decode("deprecated"); - security = object.decodeObjects("security", () => new APISecurityRequirement.empty()); - servers = object.decodeObjects("servers", () => APIServerDescription.empty()); + security = + object.decodeObjects("security", () => APISecurityRequirement.empty()); + servers = + object.decodeObjects("servers", () => APIServerDescription.empty()); } void encode(KeyedArchive object) { super.encode(object); if (responses == null) { - throw new ArgumentError("Invalid specification. APIOperation must have non-null values for: 'responses'."); + throw ArgumentError( + "Invalid specification. APIOperation must have non-null values for: 'responses'."); } object.encode("tags", tags); diff --git a/lib/src/v3/parameter.dart b/lib/src/v3/parameter.dart index 02bbd1f..f39f410 100644 --- a/lib/src/v3/parameter.dart +++ b/lib/src/v3/parameter.dart @@ -30,7 +30,7 @@ enum APIParameterLocation { } class APIParameterLocationCodec { - static APIParameterLocation decode(String location) { + static APIParameterLocation? decode(String location) { switch (location) { case "query": return APIParameterLocation.query; @@ -40,12 +40,12 @@ class APIParameterLocationCodec { return APIParameterLocation.path; case "cookie": return APIParameterLocation.cookie; + default: + return null; } - - return null; } - static String encode(APIParameterLocation location) { + static String? encode(APIParameterLocation location) { switch (location) { case APIParameterLocation.query: return "query"; @@ -55,8 +55,9 @@ class APIParameterLocationCodec { return "path"; case APIParameterLocation.cookie: return "cookie"; + default: + return null; } - return null; } } @@ -71,16 +72,16 @@ class APIParameter extends APIObject { this.schema, this.content, this.style, - bool required, - bool deprecated, - bool allowEmptyValue, - bool explode, - bool allowReserved}) { - this.isRequired = required; - this.isDeprecated = deprecated; - this.allowEmptyValue = allowEmptyValue; - this.allowReserved = allowReserved; - this.explode = explode; + bool? isRequired, + bool? deprecated, + bool? allowEmptyValue, + bool? explode, + bool? allowReserved}) { + this.isRequired = isRequired ?? false; + this.isDeprecated = deprecated ?? false; + this.allowEmptyValue = allowEmptyValue ?? false; + this.allowReserved = allowReserved ?? false; + this.explode = explode ?? false; } APIParameter.header(this.name, @@ -88,16 +89,16 @@ class APIParameter extends APIObject { this.schema, this.content, this.style, - bool required, - bool deprecated, - bool allowEmptyValue, - bool explode, - bool allowReserved}) { - this.isRequired = required; - this.isDeprecated = deprecated; - this.allowEmptyValue = allowEmptyValue; - this.allowReserved = allowReserved; - this.explode = explode; + bool? isRequired, + bool? deprecated, + bool? allowEmptyValue, + bool? explode, + bool? allowReserved}) { + this.isRequired = isRequired ?? false; + this.isDeprecated = deprecated ?? false; + this.allowEmptyValue = allowEmptyValue ?? false; + this.allowReserved = allowReserved ?? false; + this.explode = explode ?? false; this.location = APIParameterLocation.header; } @@ -106,22 +107,22 @@ class APIParameter extends APIObject { this.schema, this.content, this.style, - bool required, - bool deprecated, - bool allowEmptyValue, - bool explode, - bool allowReserved}) { - this.isRequired = required; - this.isDeprecated = deprecated; - this.allowEmptyValue = allowEmptyValue; - this.allowReserved = allowReserved; - this.explode = explode; + bool? isRequired, + bool? deprecated, + bool? allowEmptyValue, + bool? explode, + bool? allowReserved}) { + this.isRequired = isRequired ?? false; + this.isDeprecated = deprecated ?? false; + this.allowEmptyValue = allowEmptyValue ?? false; + this.allowReserved = allowReserved ?? false; + this.explode = explode ?? false; this.location = APIParameterLocation.query; } APIParameter.path(this.name) : location = APIParameterLocation.path, - schema = new APISchemaObject.string(), + schema = APISchemaObject.string(), _required = true; APIParameter.cookie(this.name, @@ -129,16 +130,16 @@ class APIParameter extends APIObject { this.schema, this.content, this.style, - bool required, - bool deprecated, - bool allowEmptyValue, - bool explode, - bool allowReserved}) { - this.isRequired = required; - this.isDeprecated = deprecated; - this.allowEmptyValue = allowEmptyValue; - this.allowReserved = allowReserved; - this.explode = explode; + bool? isRequired, + bool? deprecated, + bool? allowEmptyValue, + bool? explode, + bool? allowReserved}) { + this.isRequired = isRequired ?? false; + this.isDeprecated = deprecated ?? false; + this.allowEmptyValue = allowEmptyValue ?? false; + this.allowReserved = allowReserved ?? false; + this.explode = explode ?? false; this.location = APIParameterLocation.cookie; } @@ -148,83 +149,84 @@ class APIParameter extends APIObject { /// If in is "path", the name field MUST correspond to the associated path segment from the path field in [APIDocument.paths]. See Path Templating for further information. /// If in is "header" and the name field is "Accept", "Content-Type" or "Authorization", the parameter definition SHALL be ignored. /// For all other cases, the name corresponds to the parameter name used by the in property. - String name; + String? name; /// A brief description of the parameter. /// /// This could contain examples of use. CommonMark syntax MAY be used for rich text representation. - String description; + String? description; /// Determines whether this parameter is mandatory. /// /// If the parameter location is "path", this property is REQUIRED and its value MUST be true. Otherwise, the property MAY be included and its default value is false. - bool get isRequired => (location == APIParameterLocation.path ? true : (_required ?? false)); + bool get isRequired => + (location == APIParameterLocation.path ? true : _required); set isRequired(bool f) { _required = f; } - bool _required; + bool _required = false; /// Specifies that a parameter is deprecated and SHOULD be transitioned out of usage. - bool get isDeprecated => _deprecated ?? false; + bool get isDeprecated => _deprecated; set isDeprecated(bool f) { _deprecated = f; } - bool _deprecated; + bool _deprecated = false; /// The location of the parameter. /// /// REQUIRED. Possible values are "query", "header", "path" or "cookie". - APIParameterLocation location; + APIParameterLocation? location; /// The schema defining the type used for the parameter. - APISchemaObject schema; + APISchemaObject? schema; // Sets the ability to pass empty-valued parameters. // // This is valid only for query parameters and allows sending a parameter with an empty value. Default value is false. If style is used, and if behavior is n/a (cannot be serialized), the value of allowEmptyValue SHALL be ignored. - bool get allowEmptyValue => _allowEmptyValue ?? false; + bool get allowEmptyValue => _allowEmptyValue; set allowEmptyValue(bool f) { _allowEmptyValue = f; } - bool _allowEmptyValue; + bool _allowEmptyValue = false; /// Describes how the parameter value will be serialized depending on the type of the parameter value. /// /// Default values (based on value of in): for query - form; for path - simple; for header - simple; for cookie - form. - String style; + String? style; /// When this is true, parameter values of type array or object generate separate parameters for each value of the array or key-value pair of the map. /// /// For other types of parameters this property has no effect. When style is form, the default value is true. For all other styles, the default value is false. - bool get explode => _explode ?? false; + bool get explode => _explode; set explode(bool f) { _explode = f; } - bool _explode; + bool _explode = false; /// Determines whether the parameter value SHOULD allow reserved characters, as defined by RFC3986 :/?#[]@!$&'()*+,;= to be included without percent-encoding. /// /// This property only applies to parameters with an in value of query. The default value is false. - bool get allowReserved => _allowReserved ?? false; + bool get allowReserved => _allowReserved; set allowReserved(bool f) { _allowReserved = f; } - bool _allowReserved; + bool _allowReserved = false; /// A map containing the representations for the parameter. /// /// The key is the media type and the value describes it. The map MUST only contain one entry. - Map content; + Map? content; // Currently missing: // example, examples @@ -234,29 +236,30 @@ class APIParameter extends APIObject { name = object.decode("name"); description = object.decode("description"); - location = APIParameterLocationCodec.decode(object.decode("in")); + location = APIParameterLocationCodec.decode(object.decode("in"))!; _required = object.decode("required"); _deprecated = object.decode("deprecated"); _allowEmptyValue = object.decode("allowEmptyValue"); - schema = object.decodeObject("schema", () => new APISchemaObject()); + schema = object.decodeObject("schema", () => APISchemaObject())!; style = object.decode("style"); _explode = object.decode("explode"); _allowReserved = object.decode("allowReserved"); - content = object.decodeObjectMap("content", () => new APIMediaType()); + content = object.decodeObjectMap("content", () => APIMediaType()); } void encode(KeyedArchive object) { super.encode(object); if (name == null || location == null) { - throw new ArgumentError("APIParameter must have non-null values for: 'name', 'location'."); + throw ArgumentError( + "APIParameter must have non-null values for: 'name', 'location'."); } object.encode("name", name); object.encode("description", description); - object.encode("in", APIParameterLocationCodec.encode(location)); + object.encode("in", APIParameterLocationCodec.encode(location!)); if (location == APIParameterLocation.path) { object.encode("required", true); diff --git a/lib/src/v3/path.dart b/lib/src/v3/path.dart index df52e4b..2b3213e 100644 --- a/lib/src/v3/path.dart +++ b/lib/src/v3/path.dart @@ -10,29 +10,33 @@ class APIPath extends APIObject { APIPath({this.summary, this.description, this.parameters, this.operations}); /// An optional, string summary, intended to apply to all operations in this path. - String summary; + String? summary; /// An optional, string description, intended to apply to all operations in this path. /// /// CommonMark syntax MAY be used for rich text representation. - String description; + String? description; /// A list of parameters that are applicable for all the operations described under this path. /// /// These parameters can be overridden at the operation level, but cannot be removed there. The list MUST NOT include duplicated parameters. A unique parameter is defined by a combination of a name and location. The list can use the Reference Object to link to parameters that are defined at the OpenAPI Object's components/parameters. - List parameters; + List? parameters; /// Definitions of operations on this path. /// /// Keys are lowercased HTTP methods, e.g. get, put, delete, post, etc. - Map operations; + Map? operations; /// Returns true if this path has path parameters [parameterNames]. /// /// Returns true if [parameters] contains path parameters with names that match [parameterNames] and /// both lists have the same number of elements. bool containsPathParameters(List parameterNames) { - final pathParams = parameters?.where((p) => p.location == APIParameterLocation.path)?.map((p) => p.name)?.toList() ?? []; + final pathParams = parameters + ?.where((p) => p?.location == APIParameterLocation.path) + .map((p) => p?.name) + .toList() ?? + []; if (pathParams.length != parameterNames.length) { return false; } @@ -47,15 +51,26 @@ class APIPath extends APIObject { summary = object.decode("summary"); description = object.decode("description"); - parameters = object.decodeObjects("parameters", () => new APIParameter.empty()); + parameters = + object.decodeObjects("parameters", () => APIParameter.empty())!; - final methodNames = ["get", "put", "post", "delete", "options", "head", "patch", "trace"]; + final methodNames = [ + "get", + "put", + "post", + "delete", + "options", + "head", + "patch", + "trace" + ]; methodNames.forEach((methodName) { if (!object.containsKey(methodName)) { return; } operations ??= {}; - operations[methodName] = object.decodeObject(methodName, () => new APIOperation.empty()); + operations![methodName] = + object.decodeObject(methodName, () => APIOperation.empty()); }); } @@ -66,7 +81,7 @@ class APIPath extends APIObject { object.encode("description", description); object.encodeObjects("parameters", parameters); - operations.forEach((opName, op) { + operations!.forEach((opName, op) { object.encodeObject(opName.toLowerCase(), op); }); } diff --git a/lib/src/v3/request_body.dart b/lib/src/v3/request_body.dart index 1f54bb5..dcf9c8f 100644 --- a/lib/src/v3/request_body.dart +++ b/lib/src/v3/request_body.dart @@ -6,14 +6,17 @@ import 'package:open_api/src/v3/schema.dart'; class APIRequestBody extends APIObject { APIRequestBody.empty(); - APIRequestBody(this.content, {this.description, bool required}) { - this.isRequired = required; + APIRequestBody(this.content, {this.description, bool isRequired = false}) { + this.isRequired = isRequired; } - APIRequestBody.schema(APISchemaObject schema, {Iterable contentTypes : const ["application/json"], this.description, bool required}) { - this.isRequired = required; + APIRequestBody.schema(APISchemaObject schema, + {Iterable contentTypes: const ["application/json"], + this.description, + bool isRequired = false}) { + this.isRequired = isRequired; this.content = contentTypes.fold({}, (prev, elem) { - prev[elem] = new APIMediaType(schema: schema); + prev![elem] = APIMediaType(schema: schema); return prev; }); } @@ -21,37 +24,38 @@ class APIRequestBody extends APIObject { /// A brief description of the request body. /// /// This could contain examples of use. CommonMark syntax MAY be used for rich text representation. - String description; + String? description; /// The content of the request body. /// /// REQUIRED. The key is a media type or media type range and the value describes it. For requests that match multiple keys, only the most specific key is applicable. e.g. text/plain overrides text/* - Map content; + Map? content; /// Determines if the request body is required in the request. /// /// Defaults to false. - bool get isRequired => _required ?? false; + bool get isRequired => _required; set isRequired(bool f) { _required = f; } - bool _required; + bool _required = false; void decode(KeyedArchive object) { super.decode(object); description = object.decode("description"); _required = object.decode("required"); - content = object.decodeObjectMap("content", () => new APIMediaType()); + content = object.decodeObjectMap("content", () => APIMediaType())!; } void encode(KeyedArchive object) { super.encode(object); if (content == null) { - throw new ArgumentError("APIRequestBody must have non-null values for: 'content'."); + throw ArgumentError( + "APIRequestBody must have non-null values for: 'content'."); } object.encode("description", description); diff --git a/lib/src/v3/response.dart b/lib/src/v3/response.dart index 50c9f97..2cbde39 100644 --- a/lib/src/v3/response.dart +++ b/lib/src/v3/response.dart @@ -7,9 +7,11 @@ import 'package:open_api/src/v3/schema.dart'; class APIResponse extends APIObject { APIResponse.empty(); APIResponse(this.description, {this.content, this.headers}); - APIResponse.schema(this.description, APISchemaObject schema, {Iterable contentTypes: const ["application/json"], this.headers}) { + APIResponse.schema(this.description, APISchemaObject schema, + {Iterable contentTypes: const ["application/json"], + this.headers}) { content = contentTypes.fold({}, (prev, elem) { - prev[elem] = new APIMediaType(schema: schema); + prev![elem] = APIMediaType(schema: schema); return prev; }); } @@ -17,17 +19,17 @@ class APIResponse extends APIObject { /// A short description of the response. /// /// REQUIRED. CommonMark syntax MAY be used for rich text representation. - String description; + String? description; /// Maps a header name to its definition. /// /// RFC7230 states header names are case insensitive. If a response header is defined with the name "Content-Type", it SHALL be ignored. - Map headers; + Map? headers; /// A map containing descriptions of potential response payloads. /// /// The key is a media type or media type range and the value describes it. For responses that match multiple keys, only the most specific key is applicable. e.g. text/plain overrides text/* - Map content; + Map? content; // Currently missing: // links @@ -36,10 +38,10 @@ class APIResponse extends APIObject { /// /// If [headers] is null, it is created. If the key does not exist in [headers], [header] is added for the key. /// If the key exists, [header] is not added. (To replace a header, access [headers] directly.) - void addHeader(String name, APIHeader header) { + void addHeader(String name, APIHeader? header) { headers ??= {}; - if (!headers.containsKey(name)) { - headers[name] = header; + if (!headers!.containsKey(name)) { + headers![name] = header; } } @@ -49,23 +51,21 @@ class APIResponse extends APIObject { /// /// If [content] is null, it is created. If [contentType] does not exist in [content], [bodyObject] is added for [contentType]. /// If [contentType] exists, the [bodyObject] is added the list of possible schemas that were previously added. - void addContent(String contentType, APISchemaObject bodyObject) { + void addContent(String contentType, APISchemaObject? bodyObject) { content ??= {}; final key = contentType; - final existingContent = content[key]; + final existingContent = content![key]; if (existingContent == null) { - content[key] = new APIMediaType(schema: bodyObject); + content![key] = APIMediaType(schema: bodyObject); return; } final schema = existingContent.schema; if (schema?.oneOf != null) { - schema.oneOf.add(bodyObject); + schema!.oneOf!.add(bodyObject); } else { - final container = new APISchemaObject()..oneOf = [ - schema, bodyObject - ]; + final container = APISchemaObject()..oneOf = [schema, bodyObject]; existingContent.schema = container; } } @@ -74,18 +74,18 @@ class APIResponse extends APIObject { super.decode(object); description = object.decode("description"); - content = object.decodeObjectMap("content", () => new APIMediaType()); - headers = object.decodeObjectMap("headers", () => new APIHeader()); + content = object.decodeObjectMap("content", () => APIMediaType()); + headers = object.decodeObjectMap("headers", () => APIHeader()); } void encode(KeyedArchive object) { super.encode(object); if (description == null) { - throw new ArgumentError("APIResponse must have non-null values for: 'description'."); + throw ArgumentError( + "APIResponse must have non-null values for: 'description'."); } - object.encode("description", description); object.encodeObjectMap("headers", headers); object.encodeObjectMap("content", content); diff --git a/lib/src/v3/schema.dart b/lib/src/v3/schema.dart index e34eb0c..427af54 100644 --- a/lib/src/v3/schema.dart +++ b/lib/src/v3/schema.dart @@ -22,33 +22,41 @@ class APISchemaObject extends APIObject { APISchemaObject.number() : type = APIType.number; APISchemaObject.integer() : type = APIType.integer; APISchemaObject.boolean() : type = APIType.boolean; - APISchemaObject.map({APIType ofType, APISchemaObject ofSchema, bool any: false}) : type = APIType.object { + APISchemaObject.map( + {APIType? ofType, APISchemaObject? ofSchema, bool any: false}) + : type = APIType.object { if (ofType != null) { - additionalPropertySchema = new APISchemaObject()..type = ofType; + additionalPropertySchema = APISchemaObject()..type = ofType; } else if (ofSchema != null) { additionalPropertySchema = ofSchema; } else if (any) { - } else { - throw new ArgumentError("Invalid 'APISchemaObject.map' with neither 'ofType', 'any' or 'ofSchema' specified."); + throw ArgumentError( + "Invalid 'APISchemaObject.map' with neither 'ofType', 'any' or 'ofSchema' specified."); } } - APISchemaObject.array({APIType ofType, APISchemaObject ofSchema}) : type = APIType.array { + APISchemaObject.array({APIType? ofType, APISchemaObject? ofSchema}) + : type = APIType.array { if (ofType != null) { - items = new APISchemaObject()..type = ofType; + items = APISchemaObject()..type = ofType; } else if (ofSchema != null) { items = ofSchema; } else { - throw new ArgumentError("Invalid 'APISchemaObject.array' with neither 'ofType' or 'ofSchema' specified."); + throw ArgumentError( + "Invalid 'APISchemaObject.array' with neither 'ofType' or 'ofSchema' specified."); } } - APISchemaObject.object(this.properties): type = APIType.object; - APISchemaObject.file({bool isBase64Encoded: false}) : type = APIType.string, format = isBase64Encoded ? "byte" : "binary"; + APISchemaObject.object(this.properties) : type = APIType.object; + APISchemaObject.file({bool isBase64Encoded: false}) + : type = APIType.string, + format = isBase64Encoded ? "byte" : "binary"; - APISchemaObject.freeForm() : type = APIType.object, additionalPropertyPolicy = APISchemaAdditionalPropertyPolicy.freeForm; + APISchemaObject.freeForm() + : type = APIType.object, + additionalPropertyPolicy = APISchemaAdditionalPropertyPolicy.freeForm; /// A title for the object. - String title; + String? title; /// The value of "maximum" MUST be a number, representing an upper limit /// for a numeric instance. @@ -57,7 +65,7 @@ class APISchemaObject extends APIObject { /// "exclusiveMaximum" is true and instance is less than the provided /// value, or else if the instance is less than or exactly equal to the /// provided value. - num maximum; + num? maximum; /// The value of "exclusiveMaximum" MUST be a boolean, representing /// whether the limit in "maximum" is exclusive or not. @@ -68,7 +76,7 @@ class APISchemaObject extends APIObject { /// equal to the value specified in "maximum". If "exclusiveMaximum" is /// false (or not specified), then a numeric instance MAY be equal to the /// value of "maximum". - bool exclusiveMaximum; + bool? exclusiveMaximum; /// The value of "minimum" MUST be a number, representing a lower limit /// for a numeric instance. @@ -77,7 +85,7 @@ class APISchemaObject extends APIObject { /// "exclusiveMinimum" is true and instance is greater than the provided /// value, or else if the instance is greater than or exactly equal to /// the provided value. - num minimum; + num? minimum; /// The value of "exclusiveMinimum" MUST be a boolean, representing /// whether the limit in "minimum" is exclusive or not. An undefined @@ -87,7 +95,7 @@ class APISchemaObject extends APIObject { /// equal to the value specified in "minimum". If "exclusiveMinimum" is /// false (or not specified), then a numeric instance MAY be equal to the /// value of "minimum". - bool exclusiveMinimum; + bool? exclusiveMinimum; /// The value of this keyword MUST be a non-negative integer. /// @@ -99,7 +107,7 @@ class APISchemaObject extends APIObject { /// /// The length of a string instance is defined as the number of its /// characters as defined by RFC 7159 [RFC7159]. - int maxLength; + int? maxLength; /// A string instance is valid against this keyword if its length is /// greater than, or equal to, the value of this keyword. @@ -112,7 +120,7 @@ class APISchemaObject extends APIObject { /// /// "minLength", if absent, may be considered as being present with /// integer value 0. - int minLength; + int? minLength; /// The value of this keyword MUST be a string. This string SHOULD be a /// valid regular expression, according to the ECMA 262 regular @@ -121,14 +129,14 @@ class APISchemaObject extends APIObject { /// A string instance is considered valid if the regular expression /// matches the instance successfully. Recall: regular expressions are /// not implicitly anchored. - String pattern; + String? pattern; /// The value of this keyword MUST be an integer. This integer MUST be /// greater than, or equal to, 0. /// /// An array instance is valid against "maxItems" if its size is less /// than, or equal to, the value of this keyword. - int maxItems; + int? maxItems; /// The value of this keyword MUST be an integer. This integer MUST be /// greater than, or equal to, 0. @@ -138,7 +146,7 @@ class APISchemaObject extends APIObject { /// /// If this keyword is not present, it may be considered present with a /// value of 0. - int minItems; + int? minItems; /// The value of this keyword MUST be a boolean. /// @@ -148,20 +156,20 @@ class APISchemaObject extends APIObject { /// If not present, this keyword may be considered present with boolean /// value false. - bool uniqueItems; + bool? uniqueItems; /// The value of "multipleOf" MUST be a number, strictly greater than 0. /// A numeric instance is only valid if division by this keyword's value /// results in an integer. - num multipleOf; + num? multipleOf; /// The value of this keyword MUST be an integer. This integer MUST be /// greater than, or equal to, 0. /// /// An object instance is valid against "maxProperties" if its number of /// properties is less than, or equal to, the value of this keyword. - int maxProperties; + int? maxProperties; /// The value of this keyword MUST be an integer. This integer MUST be /// greater than, or equal to, 0. @@ -171,7 +179,7 @@ class APISchemaObject extends APIObject { /// /// If this keyword is not present, it may be considered present with a /// value of 0. - int minProperties; + int? minProperties; /// The value of this keyword MUST be an array. This array MUST have at /// least one element. Elements of this array MUST be strings, and MUST @@ -179,7 +187,7 @@ class APISchemaObject extends APIObject { /// /// An object instance is valid against this keyword if its property set /// contains all elements in this keyword's array value. - List required; + List? isRequired; /// The value of this keyword MUST be an array. This array SHOULD have /// at least one element. Elements in the array SHOULD be unique. @@ -188,23 +196,23 @@ class APISchemaObject extends APIObject { /// /// An instance validates successfully against this keyword if its value /// is equal to one of the elements in this keyword's array value. - List enumerated; + List? enumerated; /* Modified JSON Schema for OpenAPI */ - APIType type; - List allOf; - List anyOf; - List oneOf; - APISchemaObject not; + APIType? type; + List? allOf; + List? anyOf; + List? oneOf; + APISchemaObject? not; - APISchemaObject items; - Map properties; - APISchemaObject additionalPropertySchema; - APISchemaAdditionalPropertyPolicy additionalPropertyPolicy; + APISchemaObject? items; + Map? properties; + APISchemaObject? additionalPropertySchema; + APISchemaAdditionalPropertyPolicy? additionalPropertyPolicy; - String description; - String format; + String? description; + String? format; dynamic defaultValue; bool get isNullable => _nullable ?? false; @@ -233,10 +241,10 @@ class APISchemaObject extends APIObject { _deprecated = n; } - bool _nullable; - bool _readOnly; - bool _writeOnly; - bool _deprecated; + bool? _nullable; + bool? _readOnly; + bool? _writeOnly; + bool? _deprecated; @override Map get castMap => {"required": cast.List(cast.String)}; @@ -259,18 +267,18 @@ class APISchemaObject extends APIObject { enumerated = object.decode("enum"); minProperties = object.decode("minProperties"); maxProperties = object.decode("maxProperties"); - required = object.decode("required"); + isRequired = object.decode("required"); // - type = APITypeCodec.decode(object.decode("type")); - allOf = object.decodeObjects("allOf", () => new APISchemaObject()); - anyOf = object.decodeObjects("anyOf", () => new APISchemaObject()); - oneOf = object.decodeObjects("oneOf", () => new APISchemaObject()); - not = object.decodeObject("not", () => new APISchemaObject()); + type = APITypeCodec.decode(object.decode("type"))!; + allOf = object.decodeObjects("allOf", () => APISchemaObject()); + anyOf = object.decodeObjects("anyOf", () => APISchemaObject()); + oneOf = object.decodeObjects("oneOf", () => APISchemaObject()); + not = object.decodeObject("not", () => APISchemaObject()); - items = object.decodeObject("items", () => new APISchemaObject()); - properties = object.decodeObjectMap("properties", () => new APISchemaObject()); + items = object.decodeObject("items", () => APISchemaObject()); + properties = object.decodeObjectMap("properties", () => APISchemaObject()); final addlProps = object["additionalProperties"]; if (addlProps is bool) { @@ -283,7 +291,8 @@ class APISchemaObject extends APIObject { additionalPropertyPolicy = APISchemaAdditionalPropertyPolicy.freeForm; } else { additionalPropertyPolicy = APISchemaAdditionalPropertyPolicy.restricted; - additionalPropertySchema = object.decodeObject("additionalProperties", () => new APISchemaObject()); + additionalPropertySchema = + object.decodeObject("additionalProperties", () => APISchemaObject()); } description = object.decode("description"); @@ -314,11 +323,11 @@ class APISchemaObject extends APIObject { object.encode("enum", enumerated); object.encode("minProperties", minProperties); object.encode("maxProperties", maxProperties); - object.encode("required", required); + object.encode("required", isRequired); // - object.encode("type", APITypeCodec.encode(type)); + object.encode("type", APITypeCodec.encode(type!)); object.encodeObjects("allOf", allOf); object.encodeObjects("anyOf", anyOf); object.encodeObjects("oneOf", oneOf); @@ -326,9 +335,11 @@ class APISchemaObject extends APIObject { object.encodeObject("items", items); if (additionalPropertyPolicy != null || additionalPropertySchema != null) { - if (additionalPropertyPolicy == APISchemaAdditionalPropertyPolicy.disallowed) { + if (additionalPropertyPolicy == + APISchemaAdditionalPropertyPolicy.disallowed) { object.encode("additionalProperties", false); - } else if (additionalPropertyPolicy == APISchemaAdditionalPropertyPolicy.freeForm) { + } else if (additionalPropertyPolicy == + APISchemaAdditionalPropertyPolicy.freeForm) { object.encode("additionalProperties", true); } else { object.encodeObject("additionalProperties", additionalPropertySchema); diff --git a/lib/src/v3/security.dart b/lib/src/v3/security.dart index be4a7da..914d24f 100644 --- a/lib/src/v3/security.dart +++ b/lib/src/v3/security.dart @@ -7,7 +7,7 @@ import 'package:open_api/src/v3/parameter.dart'; enum APISecuritySchemeType { apiKey, http, oauth2, openID } class APISecuritySchemeTypeCodec { - static APISecuritySchemeType decode(String type) { + static APISecuritySchemeType? decode(String type) { switch (type) { case "apiKey": return APISecuritySchemeType.apiKey; @@ -17,11 +17,12 @@ class APISecuritySchemeTypeCodec { return APISecuritySchemeType.oauth2; case "openID": return APISecuritySchemeType.openID; + default: + return null; } - return null; } - static String encode(APISecuritySchemeType type) { + static String? encode(APISecuritySchemeType type) { switch (type) { case APISecuritySchemeType.apiKey: return "apiKey"; @@ -31,8 +32,9 @@ class APISecuritySchemeTypeCodec { return "oauth2"; case APISecuritySchemeType.openID: return "openID"; + default: + return null; } - return null; } } @@ -45,63 +47,65 @@ class APISecurityScheme extends APIObject { APISecurityScheme.http(this.scheme) : type = APISecuritySchemeType.http; - APISecurityScheme.apiKey(this.name, this.location) : type = APISecuritySchemeType.apiKey; + APISecurityScheme.apiKey(this.name, this.location) + : type = APISecuritySchemeType.apiKey; APISecurityScheme.oauth2(this.flows) : type = APISecuritySchemeType.oauth2; - APISecurityScheme.openID(this.connectURL) : type = APISecuritySchemeType.openID; + APISecurityScheme.openID(this.connectURL) + : type = APISecuritySchemeType.openID; /// The type of the security scheme. /// /// REQUIRED. Valid values are "apiKey", "http", "oauth2", "openIdConnect". - APISecuritySchemeType type; + APISecuritySchemeType? type; /// A short description for security scheme. /// CommonMark syntax MAY be used for rich text representation. - String description; + String? description; /// The name of the header, query or cookie parameter to be used. /// /// For apiKey only. REQUIRED if so. - String name; + String? name; /// The location of the API key. /// /// Valid values are "query", "header" or "cookie". /// /// For apiKey only. REQUIRED if so. - APIParameterLocation location; + APIParameterLocation? location; /// The name of the HTTP Authorization scheme to be used in the Authorization header as defined in RFC7235. /// /// For http only. REQUIRED if so. - String scheme; + String? scheme; /// A hint to the client to identify how the bearer token is formatted. /// /// Bearer tokens are usually generated by an authorization server, so this information is primarily for documentation purposes. /// /// For http only. - String format; + String? format; /// An object containing configuration information for the flow types supported. /// /// Fixed keys are implicit, password, clientCredentials and authorizationCode. /// /// For oauth2 only. REQUIRED if so. - Map flows; + Map? flows; /// OpenId Connect URL to discover OAuth2 configuration values. /// /// This MUST be in the form of a URL. /// /// For openID only. REQUIRED if so. - Uri connectURL; + Uri? connectURL; void decode(KeyedArchive object) { super.decode(object); - type = APISecuritySchemeTypeCodec.decode(object.decode("type")); + type = APISecuritySchemeTypeCodec.decode(object.decode("type"))!; description = object.decode("description"); switch (type) { @@ -113,7 +117,8 @@ class APISecurityScheme extends APIObject { break; case APISecuritySchemeType.oauth2: { - flows = object.decodeObjectMap("flows", () => new APISecuritySchemeOAuth2Flow.empty()); + flows = object.decodeObjectMap( + "flows", () => APISecuritySchemeOAuth2Flow.empty()); } break; case APISecuritySchemeType.http: @@ -127,6 +132,9 @@ class APISecurityScheme extends APIObject { connectURL = object.decode("openIdConnectUrl"); } break; + default: + throw ArgumentError( + "APISecurityScheme must have non-null values for: 'type'."); } } @@ -134,28 +142,30 @@ class APISecurityScheme extends APIObject { super.encode(object); if (type == null) { - throw new ArgumentError("APISecurityScheme must have non-null values for: 'type'."); + throw ArgumentError( + "APISecurityScheme must have non-null values for: 'type'."); } - object.encode("type", APISecuritySchemeTypeCodec.encode(type)); + object.encode("type", APISecuritySchemeTypeCodec.encode(type!)); object.encode("description", description); switch (type) { case APISecuritySchemeType.apiKey: { if (name == null || location == null) { - throw new ArgumentError( + throw ArgumentError( "APISecurityScheme with 'apiKey' type must have non-null values for: 'name', 'location'."); } object.encode("name", name); - object.encode("in", APIParameterLocationCodec.encode(location)); + object.encode("in", APIParameterLocationCodec.encode(location!)); } break; case APISecuritySchemeType.oauth2: { if (flows == null) { - throw new ArgumentError("APISecurityScheme with 'oauth2' type must have non-null values for: 'flows'."); + throw ArgumentError( + "APISecurityScheme with 'oauth2' type must have non-null values for: 'flows'."); } object.encodeObjectMap("flows", flows); @@ -164,7 +174,8 @@ class APISecurityScheme extends APIObject { case APISecuritySchemeType.http: { if (scheme == null) { - throw new ArgumentError("APISecurityScheme with 'http' type must have non-null values for: 'scheme'."); + throw ArgumentError( + "APISecurityScheme with 'http' type must have non-null values for: 'scheme'."); } object.encode("scheme", scheme); @@ -174,11 +185,15 @@ class APISecurityScheme extends APIObject { case APISecuritySchemeType.openID: { if (connectURL == null) { - throw new ArgumentError("APISecurityScheme with 'openID' type must have non-null values for: 'connectURL'."); + throw ArgumentError( + "APISecurityScheme with 'openID' type must have non-null values for: 'connectURL'."); } object.encode("openIdConnectUrl", connectURL); } break; + default: + throw ArgumentError( + "APISecurityScheme must have non-null values for: 'type'."); } } } @@ -186,30 +201,34 @@ class APISecurityScheme extends APIObject { /// Allows configuration of the supported OAuth Flows. class APISecuritySchemeOAuth2Flow extends APIObject { APISecuritySchemeOAuth2Flow.empty(); - APISecuritySchemeOAuth2Flow.code(this.authorizationURL, this.tokenURL, this.refreshURL, this.scopes); - APISecuritySchemeOAuth2Flow.implicit(this.authorizationURL, this.refreshURL, this.scopes); - APISecuritySchemeOAuth2Flow.password(this.tokenURL, this.refreshURL, this.scopes); - APISecuritySchemeOAuth2Flow.client(this.tokenURL, this.refreshURL, this.scopes); + APISecuritySchemeOAuth2Flow.code( + this.authorizationURL, this.tokenURL, this.refreshURL, this.scopes); + APISecuritySchemeOAuth2Flow.implicit( + this.authorizationURL, this.refreshURL, this.scopes); + APISecuritySchemeOAuth2Flow.password( + this.tokenURL, this.refreshURL, this.scopes); + APISecuritySchemeOAuth2Flow.client( + this.tokenURL, this.refreshURL, this.scopes); /// The authorization URL to be used for this flow. /// /// REQUIRED. This MUST be in the form of a URL. - Uri authorizationURL; + Uri? authorizationURL; /// The token URL to be used for this flow. /// /// REQUIRED. This MUST be in the form of a URL. - Uri tokenURL; + Uri? tokenURL; /// The URL to be used for obtaining refresh tokens. /// /// This MUST be in the form of a URL. - Uri refreshURL; + Uri? refreshURL; /// The available scopes for the OAuth2 security scheme. /// /// REQUIRED. A map between the scope name and a short description for it. - Map scopes; + Map? scopes; void encode(KeyedArchive object) { super.encode(object); @@ -228,7 +247,7 @@ class APISecuritySchemeOAuth2Flow extends APIObject { tokenURL = object.decode("tokenUrl"); refreshURL = object.decode("refreshUrl"); - scopes = new Map.from(object.decode("scopes")); + scopes = Map.from(object.decode("scopes")); } } @@ -246,12 +265,12 @@ class APISecurityRequirement extends APIObject { /// Each name MUST correspond to a security scheme which is declared in [APIComponents.securitySchemes]. /// /// If the security scheme is of type [APISecuritySchemeType.oauth2] or [APISecuritySchemeType.openID], then the value is a list of scope names required for the execution. For other security scheme types, the array MUST be empty. - Map> requirements; + Map>? requirements; void encode(KeyedArchive object) { super.encode(object); - requirements.forEach((key, value) { + requirements?.forEach((key, value) { object.encode(key, value); }); } @@ -260,8 +279,8 @@ class APISecurityRequirement extends APIObject { super.decode(object); object.keys.forEach((key) { - final req = new List.from(object.decode(key)); - requirements[key] = req; + final req = List.from(object.decode(key)); + requirements?[key] = req; }); } -} \ No newline at end of file +} diff --git a/lib/src/v3/server.dart b/lib/src/v3/server.dart index a7d68c2..7944cac 100644 --- a/lib/src/v3/server.dart +++ b/lib/src/v3/server.dart @@ -4,20 +4,21 @@ import 'package:open_api/src/object.dart'; class APIServerDescription extends APIObject { APIServerDescription.empty(); APIServerDescription(this.url, {this.description, this.variables}); + /// A URL to the target host. /// /// REQUIRED. This URL supports Server Variables and MAY be relative, to indicate that the host location is relative to the location where the OpenAPI document is being served. Variable substitutions will be made when a variable is named in {brackets}. - Uri url; + late Uri url; /// An optional string describing the host designated by the URL. /// /// CommonMark syntax MAY be used for rich text representation. - String description; + String? description; /// A map between a variable name and its value. /// /// The value is used for substitution in the server's URL template. - Map variables; + Map? variables; void decode(KeyedArchive object) { super.decode(object); @@ -25,14 +26,15 @@ class APIServerDescription extends APIObject { url = object.decode("url"); description = object.decode("description"); variables = - object.decodeObjectMap("variables", () => new APIServerVariable.empty()); + object.decodeObjectMap("variables", () => APIServerVariable.empty()); } void encode(KeyedArchive object) { super.encode(object); if (url == null) { - throw new ArgumentError("APIServerDescription must have non-null values for: 'url'."); + throw ArgumentError( + "APIServerDescription must have non-null values for: 'url'."); } object.encode("url", url); @@ -44,25 +46,26 @@ class APIServerDescription extends APIObject { /// An object representing a Server Variable for server URL template substitution. class APIServerVariable extends APIObject { APIServerVariable.empty(); - APIServerVariable(this.defaultValue, {this.availableValues, this.description}); + APIServerVariable(this.defaultValue, + {this.availableValues, this.description}); /// An enumeration of string values to be used if the substitution options are from a limited set. - List availableValues; + List? availableValues; /// The default value to use for substitution, and to send, if an alternate value is not supplied. /// /// REQUIRED. Unlike the Schema Object's default, this value MUST be provided by the consumer. - String defaultValue; + String? defaultValue; /// An optional description for the server variable. /// /// CommonMark syntax MAY be used for rich text representation. - String description; + String? description; void decode(KeyedArchive object) { super.decode(object); - availableValues = new List.from(object.decode("enum")); + availableValues = List.from(object.decode("enum")); defaultValue = object.decode("default"); description = object.decode("description"); } @@ -71,7 +74,8 @@ class APIServerVariable extends APIObject { super.encode(object); if (defaultValue == null) { - throw new ArgumentError("APIServerVariable must have non-null values for: 'defaultValue'."); + throw ArgumentError( + "APIServerVariable must have non-null values for: 'defaultValue'."); } object.encode("enum", availableValues); diff --git a/lib/src/v3/types.dart b/lib/src/v3/types.dart index 569ca04..67c178a 100644 --- a/lib/src/v3/types.dart +++ b/lib/src/v3/types.dart @@ -1,7 +1,7 @@ enum APIType { string, number, integer, boolean, array, object } class APITypeCodec { - static APIType decode(String type) { + static APIType? decode(String type) { switch (type) { case "string": return APIType.string; @@ -15,11 +15,12 @@ class APITypeCodec { return APIType.array; case "object": return APIType.object; + default: + return null; } - return null; } - static String encode(APIType type) { + static String? encode(APIType type) { switch (type) { case APIType.string: return "string"; @@ -33,8 +34,8 @@ class APITypeCodec { return "array"; case APIType.object: return "object"; + default: + return null; } - - return null; } } diff --git a/pubspec.yaml b/pubspec.yaml index e459a45..3b2c1a4 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -5,11 +5,11 @@ homepage: https://github.com/stablekernel/open-api-dart author: stable|kernel environment: - sdk: ">=2.0.0 <3.0.0" + sdk: ">=2.12.0-0 <3.0.0" dependencies: - meta: ^1.1.5 - codable: ^1.0.0 + codable: + git: https://github.com/j4qfrost/dart-codable.git dev_dependencies: - test: ^1.3.0 \ No newline at end of file + test: ^1.16.4 \ No newline at end of file diff --git a/test/v2_test.dart b/test/v2_test.dart index 97b300f..2215fd6 100644 --- a/test/v2_test.dart +++ b/test/v2_test.dart @@ -8,79 +8,90 @@ import 'dart:convert'; void main() { group("Kubernetes spec", () { - APIDocument doc; - Map original; + APIDocument? doc; + Map? original; setUpAll(() { // Spec file is too large for pub, and no other way to remove from pub publish // than putting in .gitignore. Therefore, this file must be downloaded locally // to this path, from this path: https://github.com/kubernetes/kubernetes/blob/master/api/openapi-spec/swagger.json. - var file = new File("test/specs/kubernetes.json"); + var file = File("test/specs/kubernetes.json"); var contents = file.readAsStringSync(); original = json.decode(contents); - doc = new APIDocument.fromMap(original); + doc = APIDocument.fromMap(original!); }); test("Has all metadata", () { - expect(doc.version, "2.0"); - expect(doc.info.title, "Kubernetes"); - expect(doc.info.version, isNotNull); - expect(doc.host, isNull); - expect(doc.basePath, isNull); - expect(doc.tags, isNull); - expect(doc.schemes, isNull); + expect(doc!.version, "2.0"); + expect(doc!.info.title, "Kubernetes"); + expect(doc!.info.version, isNotNull); + expect(doc!.host, isNull); + expect(doc!.basePath, isNull); + expect(doc!.tags, isNull); + expect(doc!.schemes, isNull); }); test("Missing top-level objects", () { - expect(doc.consumes, isNull); - expect(original.containsKey("consumes"), false); + expect(doc!.consumes, isNull); + expect(original!.containsKey("consumes"), false); - expect(doc.produces, isNull); - expect(original.containsKey("produces"), false); + expect(doc!.produces, isNull); + expect(original!.containsKey("produces"), false); }); test("Has paths", () { - expect(doc.paths.length, greaterThan(0)); - expect(doc.paths.length, original["paths"].length); + expect(doc!.paths.length, greaterThan(0)); + expect(doc!.paths.length, original!["paths"].length); - Map originalPaths = original["paths"]; - doc.paths.forEach((k, v) { + Map originalPaths = original!["paths"]; + doc!.paths.forEach((k, v) { expect(originalPaths.keys.contains(k), true); }); }); test("Sample - Namespace", () { - var namespacePath = doc.paths["/api/v1/namespaces"]; + var namespacePath = doc!.paths["/api/v1/namespaces"]; - var getNamespace = namespacePath.operations["get"]; - expect(getNamespace.description, contains("of kind Namespace")); + var getNamespace = namespacePath!.operations["get"]; + expect(getNamespace!.description, contains("of kind Namespace")); expect(getNamespace.consumes, ["*/*"]); expect(getNamespace.produces, contains("application/json")); expect(getNamespace.produces, contains("application/yaml")); expect(getNamespace.parameters.length, 8); - expect(getNamespace.parameters.firstWhere((p) => p.name == "limit").location, APIParameterLocation.query); - expect(getNamespace.parameters.firstWhere((p) => p.name == "limit").type, APIType.integer); + expect( + getNamespace.parameters + .firstWhere((p) => p!.name == "limit")! + .location, + APIParameterLocation.query); + expect( + getNamespace.parameters.firstWhere((p) => p!.name == "limit")!.type, + APIType.integer); expect(getNamespace.responses.keys, contains("401")); expect(getNamespace.responses.keys, contains("200")); var postNamespace = namespacePath.operations["post"]; - expect(postNamespace.parameters.length, 1); - expect(postNamespace.parameters.first.name, "body"); - expect(postNamespace.parameters.first.location, APIParameterLocation.body); + expect(postNamespace!.parameters.length, 1); + expect(postNamespace.parameters.first!.name, "body"); + expect( + postNamespace.parameters.first!.location, APIParameterLocation.body); }); test("Sample - Reference", () { - var apiPath = doc.paths["/api/"]; - var apiPathGet = apiPath.operations["get"]; - var response = apiPathGet.responses["200"]; - var schema = response.schema; - expect(schema.description, contains("APIVersions lists the")); - expect(schema.required, ["versions", "serverAddressByClientCIDRs"]); - expect(schema.properties["serverAddressByClientCIDRs"].items.properties["clientCIDR"].description, contains("The CIDR")); + var apiPath = doc!.paths["/api/"]; + var apiPathGet = apiPath!.operations["get"]; + var response = apiPathGet!.responses["200"]; + var schema = response!.schema; + expect(schema!.description, contains("APIVersions lists the")); + expect(schema.isRequired, ["versions", "serverAddressByClientCIDRs"]); + expect( + schema.properties!["serverAddressByClientCIDRs"]!.items! + .properties!["clientCIDR"]!.description, + contains("The CIDR")); }); test("Can encode as JSON", () { - expect(json.encode(doc.asMap()), new isInstanceOf()); + expect( + json.encode(doc!.asMap()), (object) => object.runtimeType is String); }); }); } diff --git a/test/v3_test.dart b/test/v3_test.dart index 2eb4bea..17ad24b 100644 --- a/test/v3_test.dart +++ b/test/v3_test.dart @@ -6,36 +6,41 @@ import 'dart:convert'; void main() { group("Components and resolution", () { test("Can resolve object against registry", () { - final components = new APIComponents(); - components.schemas["foo"] = new APISchemaObject.string(); + final components = APIComponents(); + components.schemas!["foo"] = APISchemaObject.string(); - final ref = new APISchemaObject()..referenceURI = Uri.parse("/components/schemas/foo"); + final ref = APISchemaObject() + ..referenceURI = Uri.parse("/components/schemas/foo"); final orig = components.resolve(ref); - expect(orig.type, APIType.string); + expect(orig!.type, APIType.string); expect(ref.type, isNull); - final APISchemaObject constructed = components.resolveUri(Uri(path: "/components/schemas/foo")); + final APISchemaObject constructed = components + .resolveUri(Uri(path: "/components/schemas/foo")) as APISchemaObject; expect(constructed.type, APIType.string); }); test("Invalid ref uri format throws error", () { - final components = new APIComponents(); + final components = APIComponents(); try { - components.resolve(new APISchemaObject()..referenceURI = Uri.parse("#/components/schemas/foo")); + components.resolve(APISchemaObject() + ..referenceURI = Uri.parse("#/components/schemas/foo")); expect(true, false); } on ArgumentError catch (e) { expect(e.message, contains("Invalid reference URI")); } try { - components.resolve(new APISchemaObject()..referenceURI = Uri.parse("#/components/schemas")); + components.resolve(APISchemaObject() + ..referenceURI = Uri.parse("#/components/schemas")); expect(true, false); } on ArgumentError catch (e) { expect(e.message, contains("Invalid reference URI")); } try { - components.resolve(new APISchemaObject()..referenceURI = Uri.parse("/components/foobar/foo")); + components.resolve(APISchemaObject() + ..referenceURI = Uri.parse("/components/foobar/foo")); expect(true, false); } on ArgumentError catch (e) { expect(e.message, contains("Invalid reference URI")); @@ -43,156 +48,175 @@ void main() { }); test("Nonexisting component returns null", () { - final components = new APIComponents(); - expect(components.resolve(new APISchemaObject()..referenceURI = Uri.parse("/components/schemas/foo")), isNull); + APIComponents? components = APIComponents(); + expect( + components.resolve(APISchemaObject() + ..referenceURI = Uri.parse("/components/schemas/foo")), + isNull); }); test("URIs are paths internally, but fragments when serialized", () { - final doc = new APIDocument.fromMap({ + final doc = APIDocument.fromMap({ "openapi": "3.0.0", - "info": {"title":"x", "version":"1"}, + "info": {"title": "x", "version": "1"}, "paths": {}, "components": { "schemas": { "string": { "type": "string", }, - "container": { - "\$ref": "#/components/schemas/string" - } + "container": {"\$ref": "#/components/schemas/string"} } } }); - expect(doc.components.schemas["container"].referenceURI.path, "/components/schemas/string"); + expect(doc.components!.schemas!["container"]!.referenceURI!.path, + "/components/schemas/string"); - doc.components.schemas["other"] = new APISchemaObject()..referenceURI = Uri(path: "/components/schemas/container"); + doc.components!.schemas!["other"] = APISchemaObject() + ..referenceURI = Uri(path: "/components/schemas/container"); final out = doc.asMap(); - expect(out["components"]["schemas"]["container"][r"$ref"], "#/components/schemas/string"); - expect(out["components"]["schemas"]["other"][r"$ref"], "#/components/schemas/container"); + expect(out["components"]["schemas"]["container"][r"$ref"], + "#/components/schemas/string"); + expect(out["components"]["schemas"]["other"][r"$ref"], + "#/components/schemas/container"); }); }); group("Stripe spec", () { - APIDocument doc; - Map original; + APIDocument? doc; + Map? original; setUpAll(() { // Spec file is too large for pub, and no other way to remove from pub publish // than putting in .gitignore. Therefore, this file must be downloaded locally // to this path, from this path: https://raw.githubusercontent.com/stripe/openapi/master/openapi/spec3.json - var file = new File("test/specs/stripe.json"); + var file = File("test/specs/stripe.json"); var contents = file.readAsStringSync(); original = json.decode(contents); - doc = new APIDocument.fromMap(original); + doc = APIDocument.fromMap(original!); }); test("Emits same document in asMap()", () { - expect(doc.asMap(), original); + expect(doc!.asMap(), original); }); test("Has openapi version", () { - expect(doc.version, "3.0.0"); + expect(doc!.version, "3.0.0"); }); test("Has info", () { - expect(doc.info.title, "Stripe API"); - expect(doc.info.version, isNotNull); - expect(doc.info.description, "The Stripe REST API. Please see https://stripe.com/docs/api for more details."); - expect(doc.info.termsOfServiceURL.toString(), "https://stripe.com/us/terms/"); - expect(doc.info.contact.email, "dev-platform@stripe.com"); - expect(doc.info.contact.name, "Stripe Dev Platform Team"); - expect(doc.info.contact.url.toString(), "https://stripe.com"); - expect(doc.info.license, isNull); + expect(doc!.info!.title, "Stripe API"); + expect(doc!.info!.version, isNotNull); + expect(doc!.info!.description, + "The Stripe REST API. Please see https://stripe.com/docs/api for more details."); + expect(doc!.info!.termsOfServiceURL.toString(), + "https://stripe.com/us/terms/"); + expect(doc!.info!.contact!.email, "dev-platform@stripe.com"); + expect(doc!.info!.contact!.name, "Stripe Dev Platform Team"); + expect(doc!.info!.contact!.url.toString(), "https://stripe.com"); + expect(doc!.info!.license, isNull); }); test("Has servers", () { - expect(doc.servers.length, 1); - expect(doc.servers.first.url.toString(), "https://api.stripe.com/"); - expect(doc.servers.first.description, isNull); - expect(doc.servers.first.variables, isNull); + expect(doc!.servers!.length, 1); + expect(doc!.servers!.first!.url.toString(), "https://api.stripe.com/"); + expect(doc!.servers!.first!.description, isNull); + expect(doc!.servers!.first!.variables, isNull); }); test("Tags", () { - expect(doc.tags, isNull); + expect(doc!.tags, isNull); }); group("Paths", () { test("Sample path 1", () { - final p = doc.paths["/v1/transfers/{transfer}/reversals/{id}"]; + final p = doc!.paths!["/v1/transfers/{transfer}/reversals/{id}"]; expect(p, isNotNull); - expect(p.description, isNull); + expect(p!.description, isNull); - expect(p.operations.length, 2); + expect(p.operations!.length, 2); - final getOp = p.operations["get"]; - final getParams = getOp.parameters; + final getOp = p.operations!["get"]; + final getParams = getOp!.parameters; final getResponses = getOp.responses; expect(getOp.description, contains("10 most recent reversals")); expect(getOp.id, "TransferReversalRetrieve"); - expect(getParams.length, 3); - expect(getParams[0].location, APIParameterLocation.query); - expect(getParams[0].description, "Specifies which fields in the response should be expanded."); - expect(getParams[0].name, "expand"); - expect(getParams[0].isRequired, false); - expect(getParams[0].schema.type, APIType.array); - expect(getParams[0].schema.items.type, APIType.string); - - expect(getParams[1].location, APIParameterLocation.path); - expect(getParams[1].name, "id"); - expect(getParams[1].isRequired, true); - expect(getParams[1].schema.type, APIType.string); - - expect(getParams[2].location, APIParameterLocation.path); - expect(getParams[2].name, "transfer"); - expect(getParams[2].isRequired, true); - expect(getParams[2].schema.type, APIType.string); - - expect(getResponses.length, 2); - expect(getResponses["200"].content.length, 1); - expect(getResponses["200"].content["application/json"].schema.referenceURI, Uri.parse(Uri.parse("#/components/schemas/transfer_reversal").fragment)); - - final resolvedElement = getResponses["200"].content["application/json"].schema.properties["balance_transaction"].anyOf; - expect(resolvedElement.last.properties["amount"].type, APIType.integer); + expect(getParams!.length, 3); + expect(getParams[0]!.location, APIParameterLocation.query); + expect(getParams[0]!.description, + "Specifies which fields in the response should be expanded."); + expect(getParams[0]!.name, "expand"); + expect(getParams[0]!.isRequired, false); + expect(getParams[0]!.schema!.type, APIType.array); + expect(getParams[0]!.schema!.items!.type, APIType.string); + + expect(getParams[1]!.location, APIParameterLocation.path); + expect(getParams[1]!.name, "id"); + expect(getParams[1]!.isRequired, true); + expect(getParams[1]!.schema!.type, APIType.string); + + expect(getParams[2]!.location, APIParameterLocation.path); + expect(getParams[2]!.name, "transfer"); + expect(getParams[2]!.isRequired, true); + expect(getParams[2]!.schema!.type, APIType.string); + + expect(getResponses!.length, 2); + expect(getResponses["200"]!.content!.length, 1); + expect( + getResponses["200"]! + .content!["application/json"]! + .schema! + .referenceURI, + Uri.parse( + Uri.parse("#/components/schemas/transfer_reversal").fragment)); + + final resolvedElement = getResponses["200"]! + .content!["application/json"]! + .schema! + .properties!["balance_transaction"]! + .anyOf; + expect(resolvedElement!.last!.properties!["amount"]!.type, + APIType.integer); }); }); - group("Components", () { - - }); + group("Components", () {}); test("Security requirement", () { - expect(doc.security, isNull); + expect(doc!.security, isNull); }); }); group("Schema", () { test("Can read/emit schema object with additionalProperties=true", () { - final doc = new APIDocument.fromMap({ + final doc = APIDocument.fromMap({ "openapi": "3.0.0", - "info": {"title":"x", "version":"1"}, + "info": {"title": "x", "version": "1"}, "paths": {}, "components": { "schemas": { - "freeform": { - "type": "object", - "additionalProperties": true - } + "freeform": {"type": "object", "additionalProperties": true} } } }); - expect(doc.components.schemas["freeform"].additionalPropertyPolicy, APISchemaAdditionalPropertyPolicy.freeForm); + expect(doc.components!.schemas!["freeform"]!.additionalPropertyPolicy, + APISchemaAdditionalPropertyPolicy.freeForm); - expect(doc.asMap()["components"]["schemas"]["freeform"]["type"], "object"); - expect(doc.asMap()["components"]["schemas"]["freeform"]["additionalProperties"], true); + expect( + doc.asMap()["components"]["schemas"]["freeform"]["type"], "object"); + expect( + doc.asMap()["components"]["schemas"]["freeform"] + ["additionalProperties"], + true); }); test("Can read/emit schema object with additionalProperties={}", () { - final doc = new APIDocument.fromMap({ + final doc = APIDocument.fromMap({ "openapi": "3.0.0", - "info": {"title":"x", "version":"1"}, + "info": {"title": "x", "version": "1"}, "paths": {}, "components": { "schemas": { @@ -203,91 +227,121 @@ void main() { } } }); - expect(doc.components.schemas["freeform"].additionalPropertyPolicy, APISchemaAdditionalPropertyPolicy.freeForm); - expect(doc.asMap()["components"]["schemas"]["freeform"]["type"], "object"); - expect(doc.asMap()["components"]["schemas"]["freeform"]["additionalProperties"], true); + expect(doc.components!.schemas!["freeform"]!.additionalPropertyPolicy, + APISchemaAdditionalPropertyPolicy.freeForm); + expect( + doc.asMap()["components"]["schemas"]["freeform"]["type"], "object"); + expect( + doc.asMap()["components"]["schemas"]["freeform"] + ["additionalProperties"], + true); }); - }); - group("Callbacks", () { - }); + group("Callbacks", () {}); group("'add' methods", () { test("'addHeader'", () { - var resp = new APIResponse("Response"); + var resp = APIResponse("Response"); // when null - resp.addHeader("x", new APIHeader(schema: new APISchemaObject.string(format: "initial"))); - expect(resp.headers["x"].schema.format, "initial"); + resp.addHeader( + "x", APIHeader(schema: APISchemaObject.string(format: "initial"))); + expect(resp.headers!["x"]!.schema!.format, "initial"); // add more than one - resp.addHeader("y", new APIHeader(schema: new APISchemaObject.string(format: "second"))); - expect(resp.headers["x"].schema.format, "initial"); - expect(resp.headers["y"].schema.format, "second"); + resp.addHeader( + "y", APIHeader(schema: APISchemaObject.string(format: "second"))); + expect(resp.headers!["x"]!.schema!.format, "initial"); + expect(resp.headers!["y"]!.schema!.format, "second"); // cannot replace - resp.addHeader("y", new APIHeader(schema: new APISchemaObject.string(format: "third"))); - expect(resp.headers["x"].schema.format, "initial"); - expect(resp.headers["y"].schema.format, "second"); + resp.addHeader( + "y", APIHeader(schema: APISchemaObject.string(format: "third"))); + expect(resp.headers!["x"]!.schema!.format, "initial"); + expect(resp.headers!["y"]!.schema!.format, "second"); }); test("'addContent'", () { - var resp = new APIResponse("Response"); + var resp = APIResponse("Response"); // when null - resp.addContent("x/a", new APISchemaObject.string(format: "initial")); - expect(resp.content["x/a"].schema.format, "initial"); + resp.addContent("x/a", APISchemaObject.string(format: "initial")); + expect(resp.content!["x/a"]!.schema!.format, "initial"); // add more than one - resp.addContent("y/a", new APISchemaObject.string(format: "second")); - expect(resp.content["x/a"].schema.format, "initial"); - expect(resp.content["y/a"].schema.format, "second"); + resp.addContent("y/a", APISchemaObject.string(format: "second")); + expect(resp.content!["x/a"]!.schema!.format, "initial"); + expect(resp.content!["y/a"]!.schema!.format, "second"); // joins schema in oneOf if key exists - resp.addContent("y/a", new APISchemaObject.string(format: "third")); - expect(resp.content["x/a"].schema.format, "initial"); + resp.addContent("y/a", APISchemaObject.string(format: "third")); + expect(resp.content!["x/a"]!.schema!.format, "initial"); - expect(resp.content["y/a"].schema.oneOf.first.format, "second"); - expect(resp.content["y/a"].schema.oneOf.last.format, "third"); + expect(resp.content!["y/a"]!.schema!.oneOf!.first!.format, "second"); + expect(resp.content!["y/a"]!.schema!.oneOf!.last!.format, "third"); }); test("'addResponse'", () { - var op = new APIOperation("op", null); + var op = APIOperation("op", null); // when null - op.addResponse(200, new APIResponse.schema("OK", new APISchemaObject.string(format: "initial"))); - expect(op.responses["200"].content["application/json"].schema.format, "initial"); + op.addResponse(200, + APIResponse.schema("OK", APISchemaObject.string(format: "initial"))); + expect(op.responses!["200"]!.content!["application/json"]!.schema!.format, + "initial"); // add more than one - op.addResponse(400, new APIResponse.schema("KINDABAD", new APISchemaObject.string(format: "second"), headers: { - "initial": new APIHeader(schema: new APISchemaObject.string(format: "initial")) - })); - expect(op.responses["200"].content["application/json"].schema.format, "initial"); - expect(op.responses["400"].content["application/json"].schema.format, "second"); + op.addResponse( + 400, + APIResponse.schema( + "KINDABAD", APISchemaObject.string(format: "second"), headers: { + "initial": + APIHeader(schema: APISchemaObject.string(format: "initial")) + })); + expect(op.responses!["200"]!.content!["application/json"]!.schema!.format, + "initial"); + expect(op.responses!["400"]!.content!["application/json"]!.schema!.format, + "second"); // join responses when key exists - op.addResponse(400, new APIResponse.schema("REALBAD", new APISchemaObject.string(format: "third"), headers: { - "second": new APIHeader(schema: new APISchemaObject.string(format: "initial")) - })); - expect(op.responses["200"].content["application/json"].schema.format, "initial"); - - final r400 = op.responses["400"]; + op.addResponse( + 400, + APIResponse.schema("REALBAD", APISchemaObject.string(format: "third"), + headers: { + "second": + APIHeader(schema: APISchemaObject.string(format: "initial")) + })); + expect(op.responses!["200"]!.content!["application/json"]!.schema!.format, + "initial"); + + final r400 = op.responses!["400"]!; expect(r400.description, contains("KINDABAD")); expect(r400.description, contains("REALBAD")); - expect(r400.content["application/json"].schema.oneOf, isNotNull); - expect(r400.headers["initial"], isNotNull); - expect(r400.headers["second"], isNotNull); + expect(r400.content!["application/json"]!.schema!.oneOf, isNotNull); + expect(r400.headers!["initial"], isNotNull); + expect(r400.headers!["second"], isNotNull); }); test("'addResponse' guards against null value", () { - var op = new APIOperation("op", null); - - op.addResponse(400, new APIResponse.schema("KINDABAD", APISchemaObject.string(format: "second"))); - expect(op.responses["400"].content["application/json"].schema.format, "second"); - - op.addResponse(400, new APIResponse.schema("REALBAD", new APISchemaObject.string(format: "third"))); - expect(op.responses["400"].content["application/json"].schema.oneOf.length, 2); + var op = APIOperation("op", null); + + op.addResponse( + 400, + APIResponse.schema( + "KINDABAD", APISchemaObject.string(format: "second"))); + expect(op.responses!["400"]!.content!["application/json"]!.schema!.format, + "second"); + + op.addResponse( + 400, + APIResponse.schema( + "REALBAD", APISchemaObject.string(format: "third"))); + expect( + op.responses!["400"]!.content!["application/json"]!.schema!.oneOf! + .length, + 2); }); - });; + }); + ; } From 89d2c386e7d5ba5512646ee034807a9140b933d4 Mon Sep 17 00:00:00 2001 From: AnhQuan Nguyen Date: Mon, 1 Mar 2021 00:38:47 -0800 Subject: [PATCH 06/30] update travis --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d3eedb5..3c6fabc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: dart dart: - - stable + - beta before_script: - mkdir test/specs From 966f6a3a5ebc938bdf363cd73edfa9886ad3144a Mon Sep 17 00:00:00 2001 From: AnhQuan Nguyen Date: Mon, 1 Mar 2021 01:09:06 -0800 Subject: [PATCH 07/30] check null type return --- lib/src/v2/document.dart | 8 ++++---- lib/src/v3/metadata.dart | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/src/v2/document.dart b/lib/src/v2/document.dart index 5d50ebe..b46bf8d 100644 --- a/lib/src/v2/document.dart +++ b/lib/src/v2/document.dart @@ -52,10 +52,10 @@ class APIDocument extends APIObject { version = object["swagger"]; host = object["host"]; basePath = object["basePath"]; - schemes = object["schemes"]; - consumes = object["consumes"]; - produces = object["produces"]; - security = object["security"]; + schemes = object["schemes"] ?? []; + consumes = object["consumes"] ?? []; + produces = object["produces"] ?? []; + security = object["security"] ?? []; info = object.decodeObject("info", () => APIInfo())!; tags = object.decodeObjects("tags", () => APITag())!; diff --git a/lib/src/v3/metadata.dart b/lib/src/v3/metadata.dart index 206d822..3bf12fd 100644 --- a/lib/src/v3/metadata.dart +++ b/lib/src/v3/metadata.dart @@ -41,7 +41,7 @@ class APIInfo extends APIObject { title = object.decode("title"); description = object.decode("description"); - termsOfServiceURL = object.decode("termsOfService"); + termsOfServiceURL = object.decode("termsOfService") as Uri?; contact = object.decodeObject("contact", () => APIContact()); license = object.decodeObject("license", () => APILicense.empty()); version = object.decode("version"); From 322ebec8e9ab537fef77da68f218c36c10f80eb7 Mon Sep 17 00:00:00 2001 From: AnhQuan Nguyen Date: Mon, 1 Mar 2021 01:57:11 -0800 Subject: [PATCH 08/30] test large configs --- lib/src/v2/document.dart | 40 +++++++++++++++++++-------------------- lib/src/v2/metadata.dart | 12 +++++++----- lib/src/v2/operation.dart | 22 ++++++++++----------- lib/src/v2/property.dart | 8 ++++---- lib/src/v2/response.dart | 2 +- lib/src/v2/schema.dart | 2 +- lib/src/v2/types.dart | 8 ++++---- lib/src/v3/encoding.dart | 4 ++-- lib/src/v3/metadata.dart | 8 ++++++-- lib/src/v3/operation.dart | 2 +- lib/src/v3/parameter.dart | 10 +++++----- lib/src/v3/path.dart | 3 +-- lib/src/v3/schema.dart | 6 +++--- lib/src/v3/server.dart | 6 ++++-- lib/src/v3/types.dart | 4 ++-- test/v2_test.dart | 28 +++++++++++++-------------- test/v3_test.dart | 1 - 17 files changed, 86 insertions(+), 80 deletions(-) diff --git a/lib/src/v2/document.dart b/lib/src/v2/document.dart index b46bf8d..5d2f094 100644 --- a/lib/src/v2/document.dart +++ b/lib/src/v2/document.dart @@ -22,17 +22,17 @@ class APIDocument extends APIObject { String? host; String? basePath; - List tags = []; - List schemes = []; - List consumes = []; - List produces = []; - List>> security = []; + List? tags = []; + List? schemes = []; + List? consumes = []; + List? produces = []; + List>?> security = []; - Map paths = {}; - Map responses = {}; - Map parameters = {}; - Map definitions = {}; - Map securityDefinitions = {}; + Map? paths = {}; + Map? responses = {}; + Map? parameters = {}; + Map? definitions = {}; + Map? securityDefinitions = {}; Map asMap() { return KeyedArchive.archive(this, allowReferences: true); @@ -52,20 +52,20 @@ class APIDocument extends APIObject { version = object["swagger"]; host = object["host"]; basePath = object["basePath"]; - schemes = object["schemes"] ?? []; - consumes = object["consumes"] ?? []; - produces = object["produces"] ?? []; + schemes = object["schemes"]; + consumes = object["consumes"]; + produces = object["produces"]; security = object["security"] ?? []; - info = object.decodeObject("info", () => APIInfo())!; - tags = object.decodeObjects("tags", () => APITag())!; - paths = object.decodeObjectMap("paths", () => APIPath())!; - responses = object.decodeObjectMap("responses", () => APIResponse())!; - parameters = object.decodeObjectMap("parameters", () => APIParameter())!; + info = object.decodeObject("info", () => APIInfo()) ?? APIInfo(); + tags = object.decodeObjects("tags", () => APITag()); + paths = object.decodeObjectMap("paths", () => APIPath()); + responses = object.decodeObjectMap("responses", () => APIResponse()); + parameters = object.decodeObjectMap("parameters", () => APIParameter()); definitions = - object.decodeObjectMap("definitions", () => APISchemaObject())!; + object.decodeObjectMap("definitions", () => APISchemaObject()); securityDefinitions = object.decodeObjectMap( - "securityDefinitions", () => APISecurityScheme())!; + "securityDefinitions", () => APISecurityScheme()); } void encode(KeyedArchive object) { diff --git a/lib/src/v2/metadata.dart b/lib/src/v2/metadata.dart index c9f0fac..cf2e3de 100644 --- a/lib/src/v2/metadata.dart +++ b/lib/src/v2/metadata.dart @@ -6,9 +6,9 @@ class APIInfo extends APIObject { APIInfo(); String title = "API"; - String description = "Description"; - String version = "1.0"; - String termsOfServiceURL = ""; + String? description = "Description"; + String? version = "1.0"; + String? termsOfServiceURL = ""; APIContact contact = APIContact(); APILicense license = APILicense(); @@ -18,8 +18,10 @@ class APIInfo extends APIObject { title = object.decode("title"); description = object.decode("description"); termsOfServiceURL = object.decode("termsOfService"); - contact = object.decodeObject("contact", () => APIContact())!; - license = object.decodeObject("license", () => APILicense())!; + contact = + object.decodeObject("contact", () => APIContact()) ?? APIContact(); + license = + object.decodeObject("license", () => APILicense()) ?? APILicense(); version = object.decode("version"); } diff --git a/lib/src/v2/operation.dart b/lib/src/v2/operation.dart index 2d64a6b..6cffd47 100644 --- a/lib/src/v2/operation.dart +++ b/lib/src/v2/operation.dart @@ -21,26 +21,26 @@ class APIOperation extends APIObject { String? id; bool deprecated = false; - List tags = []; - List schemes = []; - List consumes = []; - List produces = []; - List parameters = []; - List>> security = []; - Map responses = {}; + List tags = []; + List schemes = []; + List consumes = []; + List produces = []; + List? parameters = []; + List>?>? security = []; + Map? responses = {}; void decode(KeyedArchive object) { super.decode(object); tags = object.decode("tags"); - summary = object.decode("summary"); - description = object.decode("description"); + summary = object.decode("summary") ?? ""; + description = object.decode("description") ?? ""; id = object.decode("operationId"); consumes = object.decode("consumes"); produces = object.decode("produces"); deprecated = object.decode("deprecated") ?? false; - parameters = object.decodeObjects("parameters", () => APIParameter())!; - responses = object.decodeObjectMap("responses", () => APIResponse())!; + parameters = object.decodeObjects("parameters", () => APIParameter()); + responses = object.decodeObjectMap("responses", () => APIResponse()); schemes = object.decode("schemes"); security = object.decode("security"); } diff --git a/lib/src/v2/property.dart b/lib/src/v2/property.dart index 4d87fe9..73ebcba 100644 --- a/lib/src/v2/property.dart +++ b/lib/src/v2/property.dart @@ -12,7 +12,7 @@ enum APISchemaRepresentation { enum APICollectionFormat { csv, ssv, tsv, pipes } class APICollectionFormatCodec { - static APICollectionFormat? decode(String location) { + static APICollectionFormat? decode(String? location) { switch (location) { case "csv": return APICollectionFormat.csv; @@ -27,7 +27,7 @@ class APICollectionFormatCodec { } } - static String? encode(APICollectionFormat location) { + static String? encode(APICollectionFormat? location) { switch (location) { case APICollectionFormat.csv: return "csv"; @@ -97,10 +97,10 @@ class APIProperty extends APIObject { void encode(KeyedArchive object) { super.encode(object); - object.encode("type", APITypeCodec.encode(type!)); + object.encode("type", APITypeCodec.encode(type)); object.encode("format", format); object.encode( - "collectionFormat", APICollectionFormatCodec.encode(collectionFormat!)); + "collectionFormat", APICollectionFormatCodec.encode(collectionFormat)); object.encode("default", defaultValue); object.encode("maximum", maximum); object.encode("exclusiveMaximum", exclusiveMaximum); diff --git a/lib/src/v2/response.dart b/lib/src/v2/response.dart index 161f074..77afad6 100644 --- a/lib/src/v2/response.dart +++ b/lib/src/v2/response.dart @@ -15,7 +15,7 @@ class APIResponse extends APIObject { description = object.decode("description"); schema = object.decodeObject("schema", () => APISchemaObject()); - headers = object.decodeObjectMap("headers", () => APIHeader())!; + headers = object.decodeObjectMap("headers", () => APIHeader()) ?? {}; } void encode(KeyedArchive object) { diff --git a/lib/src/v2/schema.dart b/lib/src/v2/schema.dart index 9f1dec6..a7daff8 100644 --- a/lib/src/v2/schema.dart +++ b/lib/src/v2/schema.dart @@ -9,7 +9,7 @@ class APISchemaObject extends APIProperty { String? title; String? description; String? example; - List isRequired = []; + List? isRequired = []; bool readOnly = false; /// Valid when type == array diff --git a/lib/src/v2/types.dart b/lib/src/v2/types.dart index 6c22a18..0c04e6c 100644 --- a/lib/src/v2/types.dart +++ b/lib/src/v2/types.dart @@ -1,7 +1,7 @@ enum APIType { string, number, integer, boolean, array, file, object } class APITypeCodec { - static APIType? decode(String type) { + static APIType? decode(String? type) { switch (type) { case "string": return APIType.string; @@ -21,7 +21,7 @@ class APITypeCodec { return null; } - static String? encode(APIType type) { + static String? encode(APIType? type) { switch (type) { case APIType.string: return "string"; @@ -37,8 +37,8 @@ class APITypeCodec { return "file"; case APIType.object: return "object"; + default: + return null; } - - return null; } } diff --git a/lib/src/v3/encoding.dart b/lib/src/v3/encoding.dart index ad3c2f8..4efe8a4 100644 --- a/lib/src/v3/encoding.dart +++ b/lib/src/v3/encoding.dart @@ -56,8 +56,8 @@ class APIEncoding extends APIObject { contentType = object.decode("contentType"); headers = object.decodeObjectMap("headers", () => APIHeader()); - _allowReserved = object.decode("allowReserved"); - _explode = object.decode("explode"); + _allowReserved = object.decode("allowReserved") ?? false; + _explode = object.decode("explode") ?? false; style = object.decode("style"); } diff --git a/lib/src/v3/metadata.dart b/lib/src/v3/metadata.dart index 3bf12fd..cf5f77a 100644 --- a/lib/src/v3/metadata.dart +++ b/lib/src/v3/metadata.dart @@ -41,7 +41,9 @@ class APIInfo extends APIObject { title = object.decode("title"); description = object.decode("description"); - termsOfServiceURL = object.decode("termsOfService") as Uri?; + termsOfServiceURL = object.decode("termsOfService") != null + ? Uri.tryParse(object.decode("termsOfService")) + : null; contact = object.decodeObject("contact", () => APIContact()); license = object.decodeObject("license", () => APILicense.empty()); version = object.decode("version"); @@ -86,7 +88,9 @@ class APIContact extends APIObject { super.decode(object); name = object.decode("name"); - url = object.decode("url"); + url = object.decode("url") != null + ? Uri.tryParse(object.decode("url")) + : null; email = object.decode("email"); } diff --git a/lib/src/v3/operation.dart b/lib/src/v3/operation.dart index 455ccbb..0cc4b3f 100644 --- a/lib/src/v3/operation.dart +++ b/lib/src/v3/operation.dart @@ -150,7 +150,7 @@ class APIOperation extends APIObject { object.decodeObject("requestBody", () => APIRequestBody.empty()); responses = object.decodeObjectMap("responses", () => APIResponse.empty()); callbacks = object.decodeObjectMap("callbacks", () => APICallback()); - _deprecated = object.decode("deprecated"); + _deprecated = object.decode("deprecated") ?? false; security = object.decodeObjects("security", () => APISecurityRequirement.empty()); servers = diff --git a/lib/src/v3/parameter.dart b/lib/src/v3/parameter.dart index f39f410..837144a 100644 --- a/lib/src/v3/parameter.dart +++ b/lib/src/v3/parameter.dart @@ -239,13 +239,13 @@ class APIParameter extends APIObject { location = APIParameterLocationCodec.decode(object.decode("in"))!; _required = object.decode("required"); - _deprecated = object.decode("deprecated"); - _allowEmptyValue = object.decode("allowEmptyValue"); + _deprecated = object.decode("deprecated") ?? false; + _allowEmptyValue = object.decode("allowEmptyValue") ?? false; - schema = object.decodeObject("schema", () => APISchemaObject())!; + schema = object.decodeObject("schema", () => APISchemaObject()); style = object.decode("style"); - _explode = object.decode("explode"); - _allowReserved = object.decode("allowReserved"); + _explode = object.decode("explode") ?? false; + _allowReserved = object.decode("allowReserved") ?? false; content = object.decodeObjectMap("content", () => APIMediaType()); } diff --git a/lib/src/v3/path.dart b/lib/src/v3/path.dart index 2b3213e..70362f5 100644 --- a/lib/src/v3/path.dart +++ b/lib/src/v3/path.dart @@ -51,8 +51,7 @@ class APIPath extends APIObject { summary = object.decode("summary"); description = object.decode("description"); - parameters = - object.decodeObjects("parameters", () => APIParameter.empty())!; + parameters = object.decodeObjects("parameters", () => APIParameter.empty()); final methodNames = [ "get", diff --git a/lib/src/v3/schema.dart b/lib/src/v3/schema.dart index 427af54..8f3b8e2 100644 --- a/lib/src/v3/schema.dart +++ b/lib/src/v3/schema.dart @@ -187,7 +187,7 @@ class APISchemaObject extends APIObject { /// /// An object instance is valid against this keyword if its property set /// contains all elements in this keyword's array value. - List? isRequired; + List? isRequired; /// The value of this keyword MUST be an array. This array SHOULD have /// at least one element. Elements in the array SHOULD be unique. @@ -271,7 +271,7 @@ class APISchemaObject extends APIObject { // - type = APITypeCodec.decode(object.decode("type"))!; + type = APITypeCodec.decode(object.decode("type")); allOf = object.decodeObjects("allOf", () => APISchemaObject()); anyOf = object.decodeObjects("anyOf", () => APISchemaObject()); oneOf = object.decodeObjects("oneOf", () => APISchemaObject()); @@ -327,7 +327,7 @@ class APISchemaObject extends APIObject { // - object.encode("type", APITypeCodec.encode(type!)); + object.encode("type", APITypeCodec.encode(type)); object.encodeObjects("allOf", allOf); object.encodeObjects("anyOf", anyOf); object.encodeObjects("oneOf", oneOf); diff --git a/lib/src/v3/server.dart b/lib/src/v3/server.dart index 7944cac..4bf18e5 100644 --- a/lib/src/v3/server.dart +++ b/lib/src/v3/server.dart @@ -8,7 +8,7 @@ class APIServerDescription extends APIObject { /// A URL to the target host. /// /// REQUIRED. This URL supports Server Variables and MAY be relative, to indicate that the host location is relative to the location where the OpenAPI document is being served. Variable substitutions will be made when a variable is named in {brackets}. - late Uri url; + Uri? url; /// An optional string describing the host designated by the URL. /// @@ -23,7 +23,9 @@ class APIServerDescription extends APIObject { void decode(KeyedArchive object) { super.decode(object); - url = object.decode("url"); + url = object.decode("url") != null + ? Uri.tryParse(object.decode("url")) + : null; description = object.decode("description"); variables = object.decodeObjectMap("variables", () => APIServerVariable.empty()); diff --git a/lib/src/v3/types.dart b/lib/src/v3/types.dart index 67c178a..55e1d44 100644 --- a/lib/src/v3/types.dart +++ b/lib/src/v3/types.dart @@ -1,7 +1,7 @@ enum APIType { string, number, integer, boolean, array, object } class APITypeCodec { - static APIType? decode(String type) { + static APIType? decode(String? type) { switch (type) { case "string": return APIType.string; @@ -20,7 +20,7 @@ class APITypeCodec { } } - static String? encode(APIType type) { + static String? encode(APIType? type) { switch (type) { case APIType.string: return "string"; diff --git a/test/v2_test.dart b/test/v2_test.dart index 2215fd6..c519f71 100644 --- a/test/v2_test.dart +++ b/test/v2_test.dart @@ -40,46 +40,46 @@ void main() { }); test("Has paths", () { - expect(doc!.paths.length, greaterThan(0)); - expect(doc!.paths.length, original!["paths"].length); + expect(doc!.paths!.length, greaterThan(0)); + expect(doc!.paths!.length, original!["paths"].length); Map originalPaths = original!["paths"]; - doc!.paths.forEach((k, v) { + doc!.paths!.forEach((k, v) { expect(originalPaths.keys.contains(k), true); }); }); test("Sample - Namespace", () { - var namespacePath = doc!.paths["/api/v1/namespaces"]; + var namespacePath = doc!.paths!["/api/v1/namespaces"]; var getNamespace = namespacePath!.operations["get"]; expect(getNamespace!.description, contains("of kind Namespace")); expect(getNamespace.consumes, ["*/*"]); expect(getNamespace.produces, contains("application/json")); expect(getNamespace.produces, contains("application/yaml")); - expect(getNamespace.parameters.length, 8); + expect(getNamespace.parameters!.length, 8); expect( - getNamespace.parameters + getNamespace.parameters! .firstWhere((p) => p!.name == "limit")! .location, APIParameterLocation.query); expect( - getNamespace.parameters.firstWhere((p) => p!.name == "limit")!.type, + getNamespace.parameters!.firstWhere((p) => p!.name == "limit")!.type, APIType.integer); - expect(getNamespace.responses.keys, contains("401")); - expect(getNamespace.responses.keys, contains("200")); + expect(getNamespace.responses!.keys, contains("401")); + expect(getNamespace.responses!.keys, contains("200")); var postNamespace = namespacePath.operations["post"]; - expect(postNamespace!.parameters.length, 1); - expect(postNamespace.parameters.first!.name, "body"); + expect(postNamespace!.parameters!.length, 1); + expect(postNamespace.parameters!.first!.name, "body"); expect( - postNamespace.parameters.first!.location, APIParameterLocation.body); + postNamespace.parameters!.first!.location, APIParameterLocation.body); }); test("Sample - Reference", () { - var apiPath = doc!.paths["/api/"]; + var apiPath = doc!.paths!["/api/"]; var apiPathGet = apiPath!.operations["get"]; - var response = apiPathGet!.responses["200"]; + var response = apiPathGet!.responses!["200"]; var schema = response!.schema; expect(schema!.description, contains("APIVersions lists the")); expect(schema.isRequired, ["versions", "serverAddressByClientCIDRs"]); diff --git a/test/v3_test.dart b/test/v3_test.dart index 17ad24b..39052be 100644 --- a/test/v3_test.dart +++ b/test/v3_test.dart @@ -343,5 +343,4 @@ void main() { 2); }); }); - ; } From aa9c66c38cfc926a41d01657fac4c6f8927d3e0a Mon Sep 17 00:00:00 2001 From: AnhQuan Nguyen Date: Mon, 1 Mar 2021 02:18:23 -0800 Subject: [PATCH 09/30] test kube config --- lib/src/v2/operation.dart | 12 +++--- lib/src/v2/parameter.dart | 12 +++--- lib/src/v2/schema.dart | 4 +- lib/src/v3/encoding.dart | 20 +++++----- lib/src/v3/operation.dart | 10 ++--- lib/src/v3/parameter.dart | 78 +++++++++++++++++++-------------------- lib/src/v3/schema.dart | 16 ++++---- 7 files changed, 76 insertions(+), 76 deletions(-) diff --git a/lib/src/v2/operation.dart b/lib/src/v2/operation.dart index 6cffd47..7d7c469 100644 --- a/lib/src/v2/operation.dart +++ b/lib/src/v2/operation.dart @@ -19,12 +19,12 @@ class APIOperation extends APIObject { String summary = ""; String description = ""; String? id; - bool deprecated = false; + bool? deprecated; - List tags = []; - List schemes = []; - List consumes = []; - List produces = []; + List? tags = []; + List? schemes = []; + List? consumes = []; + List? produces = []; List? parameters = []; List>?>? security = []; Map? responses = {}; @@ -38,7 +38,7 @@ class APIOperation extends APIObject { id = object.decode("operationId"); consumes = object.decode("consumes"); produces = object.decode("produces"); - deprecated = object.decode("deprecated") ?? false; + deprecated = object.decode("deprecated"); parameters = object.decodeObjects("parameters", () => APIParameter()); responses = object.decodeObjectMap("responses", () => APIResponse()); schemes = object.decode("schemes"); diff --git a/lib/src/v2/parameter.dart b/lib/src/v2/parameter.dart index 0fa22e7..099a24c 100644 --- a/lib/src/v2/parameter.dart +++ b/lib/src/v2/parameter.dart @@ -48,14 +48,14 @@ class APIParameter extends APIProperty { String? name; String? description; - bool required = false; + bool? isRequired = false; APIParameterLocation? location; // Valid if location is body. APISchemaObject? schema; // Valid if location is not body. - bool allowEmptyValue = false; + bool? allowEmptyValue = false; APIProperty? items; void decode(KeyedArchive json) { @@ -63,16 +63,16 @@ class APIParameter extends APIProperty { description = json.decode("description"); location = APIParameterLocationCodec.decode(json.decode("in")); if (location == APIParameterLocation.path) { - required = true; + isRequired = true; } else { - required = json.decode("required") ?? false; + isRequired = json.decode("required"); } if (location == APIParameterLocation.body) { schema = json.decodeObject("schema", () => APISchemaObject()); } else { super.decode(json); - allowEmptyValue = json.decode("allowEmptyValue") ?? false; + allowEmptyValue = json.decode("allowEmptyValue"); if (type == APIType.array) { items = json.decodeObject("items", () => APIProperty()); } @@ -83,7 +83,7 @@ class APIParameter extends APIProperty { json.encode("name", name); json.encode("description", description); json.encode("in", APIParameterLocationCodec.encode(location!)); - json.encode("required", required); + json.encode("required", isRequired); if (location == APIParameterLocation.body) { json.encodeObject("schema", schema); diff --git a/lib/src/v2/schema.dart b/lib/src/v2/schema.dart index a7daff8..3e55ab9 100644 --- a/lib/src/v2/schema.dart +++ b/lib/src/v2/schema.dart @@ -10,7 +10,7 @@ class APISchemaObject extends APIProperty { String? description; String? example; List? isRequired = []; - bool readOnly = false; + bool? readOnly = false; /// Valid when type == array APISchemaObject? items; @@ -40,7 +40,7 @@ class APISchemaObject extends APIProperty { description = json.decode("description"); isRequired = json.decode("required"); example = json.decode("example"); - readOnly = json.decode("readOnly") ?? false; + readOnly = json.decode("readOnly"); items = json.decodeObject("items", () => APISchemaObject()); additionalProperties = diff --git a/lib/src/v3/encoding.dart b/lib/src/v3/encoding.dart index 4efe8a4..5d19c3a 100644 --- a/lib/src/v3/encoding.dart +++ b/lib/src/v3/encoding.dart @@ -10,8 +10,8 @@ class APIEncoding extends APIObject { this.style, bool? allowReserved, bool? explode}) { - this.allowReserved = allowReserved ?? false; - this.explode = explode ?? false; + this.allowReserved = allowReserved; + this.explode = explode; } APIEncoding.empty(); @@ -29,22 +29,22 @@ class APIEncoding extends APIObject { /// Determines whether the parameter value SHOULD allow reserved characters, as defined by RFC3986 :/?#[]@!$&'()*+,;= to be included without percent-encoding. /// /// The default value is false. This property SHALL be ignored if the request body media type is not application/x-www-form-urlencoded. - bool get allowReserved => _allowReserved; - set allowReserved(bool f) { + bool? get allowReserved => _allowReserved; + set allowReserved(bool? f) { _allowReserved = f; } - bool _allowReserved = false; + bool? _allowReserved = false; /// When this is true, property values of type array or object generate separate parameters for each value of the array, or key-value-pair of the map. /// /// For other types of properties this property has no effect. When style is form, the default value is true. For all other styles, the default value is false. This property SHALL be ignored if the request body media type is not application/x-www-form-urlencoded. - bool get explode => _explode; - set explode(bool f) { + bool? get explode => _explode; + set explode(bool? f) { _explode = f; } - bool _explode = false; + bool? _explode = false; /// Describes how a specific property value will be serialized depending on its type. /// @@ -56,8 +56,8 @@ class APIEncoding extends APIObject { contentType = object.decode("contentType"); headers = object.decodeObjectMap("headers", () => APIHeader()); - _allowReserved = object.decode("allowReserved") ?? false; - _explode = object.decode("explode") ?? false; + _allowReserved = object.decode("allowReserved"); + _explode = object.decode("explode"); style = object.decode("style"); } diff --git a/lib/src/v3/operation.dart b/lib/src/v3/operation.dart index 0cc4b3f..2574077 100644 --- a/lib/src/v3/operation.dart +++ b/lib/src/v3/operation.dart @@ -22,7 +22,7 @@ class APIOperation extends APIObject { this.requestBody, this.callbacks, bool? deprecated}) { - isDeprecated = deprecated ?? false; + isDeprecated = deprecated; } /// A list of tags for API documentation control. @@ -76,13 +76,13 @@ class APIOperation extends APIObject { /// Declares this operation to be deprecated. /// /// Consumers SHOULD refrain from usage of the declared operation. Default value is false. - bool get isDeprecated => _deprecated; + bool? get isDeprecated => _deprecated; - set isDeprecated(bool f) { + set isDeprecated(bool? f) { _deprecated = f; } - bool _deprecated = false; + bool? _deprecated; /// Returns the parameter named [name] or null if it doesn't exist. APIParameter? parameterNamed(String name) => @@ -150,7 +150,7 @@ class APIOperation extends APIObject { object.decodeObject("requestBody", () => APIRequestBody.empty()); responses = object.decodeObjectMap("responses", () => APIResponse.empty()); callbacks = object.decodeObjectMap("callbacks", () => APICallback()); - _deprecated = object.decode("deprecated") ?? false; + _deprecated = object.decode("deprecated"); security = object.decodeObjects("security", () => APISecurityRequirement.empty()); servers = diff --git a/lib/src/v3/parameter.dart b/lib/src/v3/parameter.dart index 837144a..895fd24 100644 --- a/lib/src/v3/parameter.dart +++ b/lib/src/v3/parameter.dart @@ -77,11 +77,11 @@ class APIParameter extends APIObject { bool? allowEmptyValue, bool? explode, bool? allowReserved}) { - this.isRequired = isRequired ?? false; - this.isDeprecated = deprecated ?? false; - this.allowEmptyValue = allowEmptyValue ?? false; - this.allowReserved = allowReserved ?? false; - this.explode = explode ?? false; + this.isRequired = isRequired; + this.isDeprecated = deprecated; + this.allowEmptyValue = allowEmptyValue; + this.allowReserved = allowReserved; + this.explode = explode; } APIParameter.header(this.name, @@ -94,11 +94,11 @@ class APIParameter extends APIObject { bool? allowEmptyValue, bool? explode, bool? allowReserved}) { - this.isRequired = isRequired ?? false; - this.isDeprecated = deprecated ?? false; - this.allowEmptyValue = allowEmptyValue ?? false; - this.allowReserved = allowReserved ?? false; - this.explode = explode ?? false; + this.isRequired = isRequired; + this.isDeprecated = deprecated; + this.allowEmptyValue = allowEmptyValue; + this.allowReserved = allowReserved; + this.explode = explode; this.location = APIParameterLocation.header; } @@ -112,11 +112,11 @@ class APIParameter extends APIObject { bool? allowEmptyValue, bool? explode, bool? allowReserved}) { - this.isRequired = isRequired ?? false; - this.isDeprecated = deprecated ?? false; - this.allowEmptyValue = allowEmptyValue ?? false; - this.allowReserved = allowReserved ?? false; - this.explode = explode ?? false; + this.isRequired = isRequired; + this.isDeprecated = deprecated; + this.allowEmptyValue = allowEmptyValue; + this.allowReserved = allowReserved; + this.explode = explode; this.location = APIParameterLocation.query; } @@ -135,11 +135,11 @@ class APIParameter extends APIObject { bool? allowEmptyValue, bool? explode, bool? allowReserved}) { - this.isRequired = isRequired ?? false; - this.isDeprecated = deprecated ?? false; - this.allowEmptyValue = allowEmptyValue ?? false; - this.allowReserved = allowReserved ?? false; - this.explode = explode ?? false; + this.isRequired = isRequired; + this.isDeprecated = deprecated; + this.allowEmptyValue = allowEmptyValue; + this.allowReserved = allowReserved; + this.explode = explode; this.location = APIParameterLocation.cookie; } @@ -159,23 +159,23 @@ class APIParameter extends APIObject { /// Determines whether this parameter is mandatory. /// /// If the parameter location is "path", this property is REQUIRED and its value MUST be true. Otherwise, the property MAY be included and its default value is false. - bool get isRequired => + bool? get isRequired => (location == APIParameterLocation.path ? true : _required); - set isRequired(bool f) { + set isRequired(bool? f) { _required = f; } - bool _required = false; + bool? _required = false; /// Specifies that a parameter is deprecated and SHOULD be transitioned out of usage. - bool get isDeprecated => _deprecated; + bool? get isDeprecated => _deprecated; - set isDeprecated(bool f) { + set isDeprecated(bool? f) { _deprecated = f; } - bool _deprecated = false; + bool? _deprecated = false; /// The location of the parameter. /// @@ -188,13 +188,13 @@ class APIParameter extends APIObject { // Sets the ability to pass empty-valued parameters. // // This is valid only for query parameters and allows sending a parameter with an empty value. Default value is false. If style is used, and if behavior is n/a (cannot be serialized), the value of allowEmptyValue SHALL be ignored. - bool get allowEmptyValue => _allowEmptyValue; + bool? get allowEmptyValue => _allowEmptyValue; - set allowEmptyValue(bool f) { + set allowEmptyValue(bool? f) { _allowEmptyValue = f; } - bool _allowEmptyValue = false; + bool? _allowEmptyValue = false; /// Describes how the parameter value will be serialized depending on the type of the parameter value. /// @@ -204,24 +204,24 @@ class APIParameter extends APIObject { /// When this is true, parameter values of type array or object generate separate parameters for each value of the array or key-value pair of the map. /// /// For other types of parameters this property has no effect. When style is form, the default value is true. For all other styles, the default value is false. - bool get explode => _explode; + bool? get explode => _explode; - set explode(bool f) { + set explode(bool? f) { _explode = f; } - bool _explode = false; + bool? _explode = false; /// Determines whether the parameter value SHOULD allow reserved characters, as defined by RFC3986 :/?#[]@!$&'()*+,;= to be included without percent-encoding. /// /// This property only applies to parameters with an in value of query. The default value is false. - bool get allowReserved => _allowReserved; + bool? get allowReserved => _allowReserved; - set allowReserved(bool f) { + set allowReserved(bool? f) { _allowReserved = f; } - bool _allowReserved = false; + bool? _allowReserved = false; /// A map containing the representations for the parameter. /// @@ -239,13 +239,13 @@ class APIParameter extends APIObject { location = APIParameterLocationCodec.decode(object.decode("in"))!; _required = object.decode("required"); - _deprecated = object.decode("deprecated") ?? false; - _allowEmptyValue = object.decode("allowEmptyValue") ?? false; + _deprecated = object.decode("deprecated"); + _allowEmptyValue = object.decode("allowEmptyValue"); schema = object.decodeObject("schema", () => APISchemaObject()); style = object.decode("style"); - _explode = object.decode("explode") ?? false; - _allowReserved = object.decode("allowReserved") ?? false; + _explode = object.decode("explode"); + _allowReserved = object.decode("allowReserved"); content = object.decodeObjectMap("content", () => APIMediaType()); } diff --git a/lib/src/v3/schema.dart b/lib/src/v3/schema.dart index 8f3b8e2..4d00be1 100644 --- a/lib/src/v3/schema.dart +++ b/lib/src/v3/schema.dart @@ -215,29 +215,29 @@ class APISchemaObject extends APIObject { String? format; dynamic defaultValue; - bool get isNullable => _nullable ?? false; + bool? get isNullable => _nullable; - set isNullable(bool n) { + set isNullable(bool? n) { _nullable = n; } // APIDiscriminator discriminator; - bool get isReadOnly => _readOnly ?? false; + bool? get isReadOnly => _readOnly; - set isReadOnly(bool n) { + set isReadOnly(bool? n) { _readOnly = n; } - bool get isWriteOnly => _writeOnly ?? false; + bool? get isWriteOnly => _writeOnly; - set isWriteOnly(bool n) { + set isWriteOnly(bool? n) { _writeOnly = n; } - bool get isDeprecated => _deprecated ?? false; + bool? get isDeprecated => _deprecated; - set isDeprecated(bool n) { + set isDeprecated(bool? n) { _deprecated = n; } From c237f9a2428683097a1ba6e5b920d8eed931c328 Mon Sep 17 00:00:00 2001 From: AnhQuan Nguyen Date: Mon, 1 Mar 2021 02:32:13 -0800 Subject: [PATCH 10/30] check changes --- lib/src/v2/document.dart | 6 +++--- lib/src/v2/metadata.dart | 10 ++++------ lib/src/v2/operation.dart | 8 ++++---- lib/src/v2/response.dart | 6 +++--- test/v2_test.dart | 4 ++-- 5 files changed, 16 insertions(+), 18 deletions(-) diff --git a/lib/src/v2/document.dart b/lib/src/v2/document.dart index 5d2f094..c79948b 100644 --- a/lib/src/v2/document.dart +++ b/lib/src/v2/document.dart @@ -18,7 +18,7 @@ class APIDocument extends APIObject { } String version = "2.0"; - APIInfo info = APIInfo(); + APIInfo? info = APIInfo(); String? host; String? basePath; @@ -55,9 +55,9 @@ class APIDocument extends APIObject { schemes = object["schemes"]; consumes = object["consumes"]; produces = object["produces"]; - security = object["security"] ?? []; + security = object["security"]; - info = object.decodeObject("info", () => APIInfo()) ?? APIInfo(); + info = object.decodeObject("info", () => APIInfo()); tags = object.decodeObjects("tags", () => APITag()); paths = object.decodeObjectMap("paths", () => APIPath()); responses = object.decodeObjectMap("responses", () => APIResponse()); diff --git a/lib/src/v2/metadata.dart b/lib/src/v2/metadata.dart index cf2e3de..8b674d8 100644 --- a/lib/src/v2/metadata.dart +++ b/lib/src/v2/metadata.dart @@ -9,8 +9,8 @@ class APIInfo extends APIObject { String? description = "Description"; String? version = "1.0"; String? termsOfServiceURL = ""; - APIContact contact = APIContact(); - APILicense license = APILicense(); + APIContact? contact = APIContact(); + APILicense? license = APILicense(); void decode(KeyedArchive object) { super.decode(object); @@ -18,10 +18,8 @@ class APIInfo extends APIObject { title = object.decode("title"); description = object.decode("description"); termsOfServiceURL = object.decode("termsOfService"); - contact = - object.decodeObject("contact", () => APIContact()) ?? APIContact(); - license = - object.decodeObject("license", () => APILicense()) ?? APILicense(); + contact = object.decodeObject("contact", () => APIContact()); + license = object.decodeObject("license", () => APILicense()); version = object.decode("version"); } diff --git a/lib/src/v2/operation.dart b/lib/src/v2/operation.dart index 7d7c469..f195615 100644 --- a/lib/src/v2/operation.dart +++ b/lib/src/v2/operation.dart @@ -16,8 +16,8 @@ class APIOperation extends APIObject { "security": cast.List(cast.Map(cast.String, cast.List(cast.String))), }; - String summary = ""; - String description = ""; + String? summary = ""; + String? description = ""; String? id; bool? deprecated; @@ -33,8 +33,8 @@ class APIOperation extends APIObject { super.decode(object); tags = object.decode("tags"); - summary = object.decode("summary") ?? ""; - description = object.decode("description") ?? ""; + summary = object.decode("summary"); + description = object.decode("description"); id = object.decode("operationId"); consumes = object.decode("consumes"); produces = object.decode("produces"); diff --git a/lib/src/v2/response.dart b/lib/src/v2/response.dart index 77afad6..8056706 100644 --- a/lib/src/v2/response.dart +++ b/lib/src/v2/response.dart @@ -6,16 +6,16 @@ import 'package:open_api/src/v2/schema.dart'; class APIResponse extends APIObject { APIResponse(); - String description = ""; + String? description = ""; APISchemaObject? schema; - Map headers = {}; + Map? headers = {}; void decode(KeyedArchive object) { super.decode(object); description = object.decode("description"); schema = object.decodeObject("schema", () => APISchemaObject()); - headers = object.decodeObjectMap("headers", () => APIHeader()) ?? {}; + headers = object.decodeObjectMap("headers", () => APIHeader()); } void encode(KeyedArchive object) { diff --git a/test/v2_test.dart b/test/v2_test.dart index c519f71..bba8d8d 100644 --- a/test/v2_test.dart +++ b/test/v2_test.dart @@ -23,8 +23,8 @@ void main() { test("Has all metadata", () { expect(doc!.version, "2.0"); - expect(doc!.info.title, "Kubernetes"); - expect(doc!.info.version, isNotNull); + expect(doc!.info!.title, "Kubernetes"); + expect(doc!.info!.version, isNotNull); expect(doc!.host, isNull); expect(doc!.basePath, isNull); expect(doc!.tags, isNull); From ea7a14696f570d05ae2f0ba60142d06333b5bd8f Mon Sep 17 00:00:00 2001 From: AnhQuan Nguyen Date: Mon, 1 Mar 2021 02:50:15 -0800 Subject: [PATCH 11/30] add more nulls --- lib/src/v2/operation.dart | 4 ++-- lib/src/v2/parameter.dart | 8 ++++---- lib/src/v2/schema.dart | 2 +- lib/src/v2/security.dart | 4 ++-- lib/src/v3/components.dart | 8 +++----- lib/src/v3/parameter.dart | 4 ++-- lib/src/v3/security.dart | 4 ++-- 7 files changed, 16 insertions(+), 18 deletions(-) diff --git a/lib/src/v2/operation.dart b/lib/src/v2/operation.dart index f195615..0978b9d 100644 --- a/lib/src/v2/operation.dart +++ b/lib/src/v2/operation.dart @@ -19,7 +19,7 @@ class APIOperation extends APIObject { String? summary = ""; String? description = ""; String? id; - bool? deprecated; + bool? deprecated = false; List? tags = []; List? schemes = []; @@ -38,7 +38,7 @@ class APIOperation extends APIObject { id = object.decode("operationId"); consumes = object.decode("consumes"); produces = object.decode("produces"); - deprecated = object.decode("deprecated"); + deprecated = object.decode("deprecated") ?? false; parameters = object.decodeObjects("parameters", () => APIParameter()); responses = object.decodeObjectMap("responses", () => APIResponse()); schemes = object.decode("schemes"); diff --git a/lib/src/v2/parameter.dart b/lib/src/v2/parameter.dart index 099a24c..33842f9 100644 --- a/lib/src/v2/parameter.dart +++ b/lib/src/v2/parameter.dart @@ -7,7 +7,7 @@ import 'package:open_api/src/v2/types.dart'; enum APIParameterLocation { query, header, path, formData, body } class APIParameterLocationCodec { - static APIParameterLocation? decode(String location) { + static APIParameterLocation? decode(String? location) { switch (location) { case "query": return APIParameterLocation.query; @@ -24,7 +24,7 @@ class APIParameterLocationCodec { } } - static String? encode(APIParameterLocation location) { + static String? encode(APIParameterLocation? location) { switch (location) { case APIParameterLocation.query: return "query"; @@ -65,14 +65,14 @@ class APIParameter extends APIProperty { if (location == APIParameterLocation.path) { isRequired = true; } else { - isRequired = json.decode("required"); + isRequired = json.decode("required") ?? false; } if (location == APIParameterLocation.body) { schema = json.decodeObject("schema", () => APISchemaObject()); } else { super.decode(json); - allowEmptyValue = json.decode("allowEmptyValue"); + allowEmptyValue = json.decode("allowEmptyValue") ?? false; if (type == APIType.array) { items = json.decodeObject("items", () => APIProperty()); } diff --git a/lib/src/v2/schema.dart b/lib/src/v2/schema.dart index 3e55ab9..3d5ff8d 100644 --- a/lib/src/v2/schema.dart +++ b/lib/src/v2/schema.dart @@ -40,7 +40,7 @@ class APISchemaObject extends APIProperty { description = json.decode("description"); isRequired = json.decode("required"); example = json.decode("example"); - readOnly = json.decode("readOnly"); + readOnly = json.decode("readOnly") ?? false; items = json.decodeObject("items", () => APISchemaObject()); additionalProperties = diff --git a/lib/src/v2/security.dart b/lib/src/v2/security.dart index 45cad67..90b3f84 100644 --- a/lib/src/v2/security.dart +++ b/lib/src/v2/security.dart @@ -11,7 +11,7 @@ enum APISecuritySchemeFlow { } class APISecuritySchemeFlowCodec { - static APISecuritySchemeFlow? decode(String flow) { + static APISecuritySchemeFlow? decode(String? flow) { switch (flow) { case "accessCode": return APISecuritySchemeFlow.authorizationCode; @@ -26,7 +26,7 @@ class APISecuritySchemeFlowCodec { } } - static String? encode(APISecuritySchemeFlow flow) { + static String? encode(APISecuritySchemeFlow? flow) { switch (flow) { case APISecuritySchemeFlow.authorizationCode: return "accessCode"; diff --git a/lib/src/v3/components.dart b/lib/src/v3/components.dart index fbc592e..fcfba66 100644 --- a/lib/src/v3/components.dart +++ b/lib/src/v3/components.dart @@ -78,11 +78,9 @@ class APIComponents extends APIObject { case "callbacks": namedMap = callbacks; break; - } - - if (namedMap == null) { - throw ArgumentError( - "Invalid reference URI: component type '${segments[1]}' does not exist."); + default: + throw ArgumentError( + "Invalid reference URI: component type '${segments[1]}' does not exist."); } return namedMap[segments.last]; diff --git a/lib/src/v3/parameter.dart b/lib/src/v3/parameter.dart index 895fd24..df82829 100644 --- a/lib/src/v3/parameter.dart +++ b/lib/src/v3/parameter.dart @@ -30,7 +30,7 @@ enum APIParameterLocation { } class APIParameterLocationCodec { - static APIParameterLocation? decode(String location) { + static APIParameterLocation? decode(String? location) { switch (location) { case "query": return APIParameterLocation.query; @@ -45,7 +45,7 @@ class APIParameterLocationCodec { } } - static String? encode(APIParameterLocation location) { + static String? encode(APIParameterLocation? location) { switch (location) { case APIParameterLocation.query: return "query"; diff --git a/lib/src/v3/security.dart b/lib/src/v3/security.dart index 914d24f..6f5ee8d 100644 --- a/lib/src/v3/security.dart +++ b/lib/src/v3/security.dart @@ -7,7 +7,7 @@ import 'package:open_api/src/v3/parameter.dart'; enum APISecuritySchemeType { apiKey, http, oauth2, openID } class APISecuritySchemeTypeCodec { - static APISecuritySchemeType? decode(String type) { + static APISecuritySchemeType? decode(String? type) { switch (type) { case "apiKey": return APISecuritySchemeType.apiKey; @@ -22,7 +22,7 @@ class APISecuritySchemeTypeCodec { } } - static String? encode(APISecuritySchemeType type) { + static String? encode(APISecuritySchemeType? type) { switch (type) { case APISecuritySchemeType.apiKey: return "apiKey"; From 789d1cedbf9b76aa29bc51e572163333310a6203 Mon Sep 17 00:00:00 2001 From: AnhQuan Nguyen Date: Mon, 1 Mar 2021 02:55:56 -0800 Subject: [PATCH 12/30] i am a dumb dumb --- test/v2_test.dart | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/v2_test.dart b/test/v2_test.dart index bba8d8d..1f2885b 100644 --- a/test/v2_test.dart +++ b/test/v2_test.dart @@ -90,8 +90,7 @@ void main() { }); test("Can encode as JSON", () { - expect( - json.encode(doc!.asMap()), (object) => object.runtimeType is String); + expect(json.encode(doc!.asMap()), (object) => isA()); }); }); } From eff3ce3763969ed0110ecb745f2266d666f2fa3a Mon Sep 17 00:00:00 2001 From: AnhQuan Nguyen Date: Mon, 1 Mar 2021 02:58:02 -0800 Subject: [PATCH 13/30] still dumb and should run locally --- test/v2_test.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/v2_test.dart b/test/v2_test.dart index 1f2885b..f56f66c 100644 --- a/test/v2_test.dart +++ b/test/v2_test.dart @@ -90,7 +90,7 @@ void main() { }); test("Can encode as JSON", () { - expect(json.encode(doc!.asMap()), (object) => isA()); + expect(json.encode(doc!.asMap()), isA()); }); }); } From 9cf53f00606604fd8f45a44e085fe91ede3ed36f Mon Sep 17 00:00:00 2001 From: AnhQuan Nguyen Date: Mon, 1 Mar 2021 03:02:48 -0800 Subject: [PATCH 14/30] revert some bool fields --- lib/src/v2/operation.dart | 2 +- lib/src/v2/parameter.dart | 4 ++-- lib/src/v2/schema.dart | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/src/v2/operation.dart b/lib/src/v2/operation.dart index 0978b9d..1edbf91 100644 --- a/lib/src/v2/operation.dart +++ b/lib/src/v2/operation.dart @@ -19,7 +19,7 @@ class APIOperation extends APIObject { String? summary = ""; String? description = ""; String? id; - bool? deprecated = false; + bool deprecated = false; List? tags = []; List? schemes = []; diff --git a/lib/src/v2/parameter.dart b/lib/src/v2/parameter.dart index 33842f9..a6e14a6 100644 --- a/lib/src/v2/parameter.dart +++ b/lib/src/v2/parameter.dart @@ -48,14 +48,14 @@ class APIParameter extends APIProperty { String? name; String? description; - bool? isRequired = false; + bool isRequired = false; APIParameterLocation? location; // Valid if location is body. APISchemaObject? schema; // Valid if location is not body. - bool? allowEmptyValue = false; + bool allowEmptyValue = false; APIProperty? items; void decode(KeyedArchive json) { diff --git a/lib/src/v2/schema.dart b/lib/src/v2/schema.dart index 3d5ff8d..a7daff8 100644 --- a/lib/src/v2/schema.dart +++ b/lib/src/v2/schema.dart @@ -10,7 +10,7 @@ class APISchemaObject extends APIProperty { String? description; String? example; List? isRequired = []; - bool? readOnly = false; + bool readOnly = false; /// Valid when type == array APISchemaObject? items; From 278d80d66e434e024fc222f04f0efe8674fde13c Mon Sep 17 00:00:00 2001 From: AnhQuan Nguyen Date: Mon, 8 Mar 2021 00:17:31 -0800 Subject: [PATCH 15/30] containsPathParameters parameterNames nullable --- lib/src/v3/path.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/v3/path.dart b/lib/src/v3/path.dart index 70362f5..4ee6ac7 100644 --- a/lib/src/v3/path.dart +++ b/lib/src/v3/path.dart @@ -31,7 +31,7 @@ class APIPath extends APIObject { /// /// Returns true if [parameters] contains path parameters with names that match [parameterNames] and /// both lists have the same number of elements. - bool containsPathParameters(List parameterNames) { + bool containsPathParameters(List parameterNames) { final pathParams = parameters ?.where((p) => p?.location == APIParameterLocation.path) .map((p) => p?.name) From 5f0f37c3e7d326e0634e2d4af618142bd32ed011 Mon Sep 17 00:00:00 2001 From: AnhQuan Nguyen Date: Mon, 8 Mar 2021 22:44:38 -0800 Subject: [PATCH 16/30] oops --- lib/src/v3/schema.dart | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/src/v3/schema.dart b/lib/src/v3/schema.dart index 4d00be1..798ef59 100644 --- a/lib/src/v3/schema.dart +++ b/lib/src/v3/schema.dart @@ -215,7 +215,7 @@ class APISchemaObject extends APIObject { String? format; dynamic defaultValue; - bool? get isNullable => _nullable; + bool? get isNullable => _nullable ?? false; set isNullable(bool? n) { _nullable = n; @@ -223,19 +223,19 @@ class APISchemaObject extends APIObject { // APIDiscriminator discriminator; - bool? get isReadOnly => _readOnly; + bool? get isReadOnly => _readOnly ?? false; set isReadOnly(bool? n) { _readOnly = n; } - bool? get isWriteOnly => _writeOnly; + bool? get isWriteOnly => _writeOnly ?? false; set isWriteOnly(bool? n) { _writeOnly = n; } - bool? get isDeprecated => _deprecated; + bool? get isDeprecated => _deprecated ?? false; set isDeprecated(bool? n) { _deprecated = n; From d5e895e0189565715a9d133fc33ac1e4806749cc Mon Sep 17 00:00:00 2001 From: AnhQuan Nguyen Date: Mon, 8 Mar 2021 23:56:06 -0800 Subject: [PATCH 17/30] try non nullable --- lib/src/v3/path.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/v3/path.dart b/lib/src/v3/path.dart index 4ee6ac7..70362f5 100644 --- a/lib/src/v3/path.dart +++ b/lib/src/v3/path.dart @@ -31,7 +31,7 @@ class APIPath extends APIObject { /// /// Returns true if [parameters] contains path parameters with names that match [parameterNames] and /// both lists have the same number of elements. - bool containsPathParameters(List parameterNames) { + bool containsPathParameters(List parameterNames) { final pathParams = parameters ?.where((p) => p?.location == APIParameterLocation.path) .map((p) => p?.name) From 535ad56bca712f6584c812b20f4da1888c9476d2 Mon Sep 17 00:00:00 2001 From: Herbert Poul Date: Wed, 10 Mar 2021 20:53:34 +0000 Subject: [PATCH 18/30] fixed tests. --- test/v3_test.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/v3_test.dart b/test/v3_test.dart index 764d6ba..5b9400b 100644 --- a/test/v3_test.dart +++ b/test/v3_test.dart @@ -207,7 +207,7 @@ void main() { }, }, }); - expect(doc.paths.values.first.operations.values.first.security, + expect(doc.paths!.values.first!.operations!.values.first?.security, hasLength(1)); }); }); From 3089d6d9e98a608fc66e0e0195eaa5ff8d1dcf7f Mon Sep 17 00:00:00 2001 From: Herbert Poul Date: Wed, 10 Mar 2021 20:54:04 +0000 Subject: [PATCH 19/30] depend on codable_forked --- pubspec.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pubspec.yaml b/pubspec.yaml index df318d2..fbef8af 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -8,8 +8,7 @@ environment: sdk: ">=2.12.0 <3.0.0" dependencies: - codable: - git: https://github.com/j4qfrost/dart-codable.git + codable_forked: ^1.0.0 dev_dependencies: test: ^1.16.4 From 1f9f3957a168158b0e8150582918ef19b6e4cfb9 Mon Sep 17 00:00:00 2001 From: Herbert Poul Date: Wed, 10 Mar 2021 20:54:55 +0000 Subject: [PATCH 20/30] sed -i '' 's/package:codable/package:codable_forked/g' `find . -name '*.dart' | xargs` --- lib/src/object.dart | 4 ++-- lib/src/v2/document.dart | 2 +- lib/src/v2/header.dart | 2 +- lib/src/v2/operation.dart | 2 +- lib/src/v2/parameter.dart | 2 +- lib/src/v2/schema.dart | 4 ++-- lib/src/v2/security.dart | 2 +- lib/src/v3/header.dart | 2 +- lib/src/v3/operation.dart | 2 +- lib/src/v3/schema.dart | 2 +- 10 files changed, 12 insertions(+), 12 deletions(-) diff --git a/lib/src/object.dart b/lib/src/object.dart index effa9ba..9212ae4 100644 --- a/lib/src/object.dart +++ b/lib/src/object.dart @@ -1,7 +1,7 @@ import 'package:meta/meta.dart'; -import 'package:codable/codable.dart'; +import 'package:codable_forked/codable.dart'; -export 'package:codable/codable.dart'; +export 'package:codable_forked/codable.dart'; class APIObject extends Coding { Map extensions = {}; diff --git a/lib/src/v2/document.dart b/lib/src/v2/document.dart index 6d7279b..7c48902 100644 --- a/lib/src/v2/document.dart +++ b/lib/src/v2/document.dart @@ -1,4 +1,4 @@ -import 'package:codable/cast.dart' as cast; +import 'package:codable_forked/cast.dart' as cast; import 'package:open_api_forked/src/object.dart'; import 'package:open_api_forked/src/v2/metadata.dart'; import 'package:open_api_forked/src/v2/parameter.dart'; diff --git a/lib/src/v2/header.dart b/lib/src/v2/header.dart index 806c1a3..ff572ad 100644 --- a/lib/src/v2/header.dart +++ b/lib/src/v2/header.dart @@ -1,4 +1,4 @@ -import 'package:codable/codable.dart'; +import 'package:codable_forked/codable.dart'; import 'package:open_api_forked/src/v2/property.dart'; import 'package:open_api_forked/src/v2/types.dart'; diff --git a/lib/src/v2/operation.dart b/lib/src/v2/operation.dart index f37244a..5a60a0e 100644 --- a/lib/src/v2/operation.dart +++ b/lib/src/v2/operation.dart @@ -1,4 +1,4 @@ -import 'package:codable/cast.dart' as cast; +import 'package:codable_forked/cast.dart' as cast; import 'package:open_api_forked/src/object.dart'; import 'package:open_api_forked/src/v2/parameter.dart'; import 'package:open_api_forked/src/v2/response.dart'; diff --git a/lib/src/v2/parameter.dart b/lib/src/v2/parameter.dart index ab5d10f..c0932f0 100644 --- a/lib/src/v2/parameter.dart +++ b/lib/src/v2/parameter.dart @@ -1,4 +1,4 @@ -import 'package:codable/codable.dart'; +import 'package:codable_forked/codable.dart'; import 'package:open_api_forked/src/v2/property.dart'; import 'package:open_api_forked/src/v2/schema.dart'; import 'package:open_api_forked/src/v2/types.dart'; diff --git a/lib/src/v2/schema.dart b/lib/src/v2/schema.dart index 39f37b9..d81ed4b 100644 --- a/lib/src/v2/schema.dart +++ b/lib/src/v2/schema.dart @@ -1,5 +1,5 @@ -import 'package:codable/cast.dart' as cast; -import 'package:codable/codable.dart'; +import 'package:codable_forked/cast.dart' as cast; +import 'package:codable_forked/codable.dart'; import 'package:open_api_forked/src/v2/property.dart'; /// Represents a schema object in the OpenAPI specification. diff --git a/lib/src/v2/security.dart b/lib/src/v2/security.dart index ed795f6..b346f30 100644 --- a/lib/src/v2/security.dart +++ b/lib/src/v2/security.dart @@ -1,4 +1,4 @@ -import 'package:codable/cast.dart' as cast; +import 'package:codable_forked/cast.dart' as cast; import 'package:open_api_forked/src/object.dart'; import 'package:open_api_forked/src/v2/parameter.dart'; diff --git a/lib/src/v3/header.dart b/lib/src/v3/header.dart index b614520..91839bc 100644 --- a/lib/src/v3/header.dart +++ b/lib/src/v3/header.dart @@ -1,4 +1,4 @@ -import 'package:codable/codable.dart'; +import 'package:codable_forked/codable.dart'; import 'package:open_api_forked/src/v3/parameter.dart'; import 'package:open_api_forked/src/v3/schema.dart'; diff --git a/lib/src/v3/operation.dart b/lib/src/v3/operation.dart index f386789..b5d4466 100644 --- a/lib/src/v3/operation.dart +++ b/lib/src/v3/operation.dart @@ -1,4 +1,4 @@ -import 'package:codable/cast.dart' as cast; +import 'package:codable_forked/cast.dart' as cast; import 'package:open_api_forked/src/object.dart'; import 'package:open_api_forked/src/v3/callback.dart'; import 'package:open_api_forked/src/v3/parameter.dart'; diff --git a/lib/src/v3/schema.dart b/lib/src/v3/schema.dart index 14d1ab2..23e104f 100644 --- a/lib/src/v3/schema.dart +++ b/lib/src/v3/schema.dart @@ -1,4 +1,4 @@ -import 'package:codable/cast.dart' as cast; +import 'package:codable_forked/cast.dart' as cast; import 'package:open_api_forked/src/object.dart'; import 'package:open_api_forked/src/v3/types.dart'; From cf8d27d995abefdaec851824843e238aa1410af4 Mon Sep 17 00:00:00 2001 From: Herbert Poul Date: Wed, 10 Mar 2021 21:00:52 +0000 Subject: [PATCH 21/30] increase version to 3.0.0 --- CHANGELOG.md | 4 ++++ pubspec.yaml | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 383ef93..8d78410 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 3.0.0 + +- nullsafety migration + ## 2.0.1+1 - forked version to fix v3 security requirements diff --git a/pubspec.yaml b/pubspec.yaml index fbef8af..c15c901 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: open_api_forked description: Data structures for OpenAPI (Swagger) specification. Reads and writes JSON specifications. -version: 2.0.1+1 +version: 3.0.0 homepage: https://github.com/stablekernel/open-api-dart author: stable|kernel @@ -9,6 +9,7 @@ environment: dependencies: codable_forked: ^1.0.0 + meta: ^1.3.0 dev_dependencies: test: ^1.16.4 From 3c7e873ad73ddc9a96d890bc672861abe3c7445a Mon Sep 17 00:00:00 2001 From: Herbert Poul Date: Fri, 19 Mar 2021 21:36:18 +0000 Subject: [PATCH 22/30] rename isRequired to required --- CHANGELOG.md | 4 ++++ analysis_options.yaml | 1 - lib/src/v2/schema.dart | 6 +++--- lib/src/v3/schema.dart | 6 +++--- pubspec.yaml | 2 +- test/v2_test.dart | 2 +- 6 files changed, 12 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d78410..67493ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 3.0.0+1 + +- Rename APISchemaObject.isRequired back to required + ## 3.0.0 - nullsafety migration diff --git a/analysis_options.yaml b/analysis_options.yaml index 97f0908..97d4b47 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -1,5 +1,4 @@ analyzer: - strong-mode: true # exclude: # - path/to/excluded/files/** diff --git a/lib/src/v2/schema.dart b/lib/src/v2/schema.dart index d81ed4b..e07336b 100644 --- a/lib/src/v2/schema.dart +++ b/lib/src/v2/schema.dart @@ -9,7 +9,7 @@ class APISchemaObject extends APIProperty { String? title; String? description; String? example; - List? isRequired = []; + List? required = []; bool readOnly = false; /// Valid when type == array @@ -38,7 +38,7 @@ class APISchemaObject extends APIProperty { title = json.decode("title"); description = json.decode("description"); - isRequired = json.decode("required"); + required = json.decode("required"); example = json.decode("example"); readOnly = json.decode("readOnly") ?? false; @@ -53,7 +53,7 @@ class APISchemaObject extends APIProperty { json.encode("title", title); json.encode("description", description); - json.encode("required", isRequired); + json.encode("required", required); json.encode("example", example); json.encode("readOnly", readOnly); diff --git a/lib/src/v3/schema.dart b/lib/src/v3/schema.dart index 23e104f..c24f8f8 100644 --- a/lib/src/v3/schema.dart +++ b/lib/src/v3/schema.dart @@ -187,7 +187,7 @@ class APISchemaObject extends APIObject { /// /// An object instance is valid against this keyword if its property set /// contains all elements in this keyword's array value. - List? isRequired; + List? required; /// The value of this keyword MUST be an array. This array SHOULD have /// at least one element. Elements in the array SHOULD be unique. @@ -267,7 +267,7 @@ class APISchemaObject extends APIObject { enumerated = object.decode("enum"); minProperties = object.decode("minProperties"); maxProperties = object.decode("maxProperties"); - isRequired = object.decode("required"); + required = object.decode("required"); // @@ -323,7 +323,7 @@ class APISchemaObject extends APIObject { object.encode("enum", enumerated); object.encode("minProperties", minProperties); object.encode("maxProperties", maxProperties); - object.encode("required", isRequired); + object.encode("required", required); // diff --git a/pubspec.yaml b/pubspec.yaml index c15c901..447e917 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: open_api_forked description: Data structures for OpenAPI (Swagger) specification. Reads and writes JSON specifications. -version: 3.0.0 +version: 3.0.0+1 homepage: https://github.com/stablekernel/open-api-dart author: stable|kernel diff --git a/test/v2_test.dart b/test/v2_test.dart index 14a00dd..a5494b2 100644 --- a/test/v2_test.dart +++ b/test/v2_test.dart @@ -82,7 +82,7 @@ void main() { var response = apiPathGet!.responses!["200"]; var schema = response!.schema; expect(schema!.description, contains("APIVersions lists the")); - expect(schema.isRequired, ["versions", "serverAddressByClientCIDRs"]); + expect(schema.required, ["versions", "serverAddressByClientCIDRs"]); expect( schema.properties!["serverAddressByClientCIDRs"]!.items! .properties!["clientCIDR"]!.description, From 3554723e29d7717a22c8d287cdadc295e01d1868 Mon Sep 17 00:00:00 2001 From: Herbert Poul Date: Fri, 19 Mar 2021 21:39:22 +0000 Subject: [PATCH 23/30] point homepage to forked repo. --- CHANGELOG.md | 2 +- pubspec.yaml | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 67493ae..7ef1eb1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## 3.0.0+1 +## 3.0.0+2 - Rename APISchemaObject.isRequired back to required diff --git a/pubspec.yaml b/pubspec.yaml index 447e917..76d8943 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,8 @@ name: open_api_forked -description: Data structures for OpenAPI (Swagger) specification. Reads and writes JSON specifications. -version: 3.0.0+1 -homepage: https://github.com/stablekernel/open-api-dart +description: Data structures for OpenAPI (Swagger) specification. Reads and writes JSON specifications. Fork, with a couple of fixes and null safety by @hpoul +version: 3.0.0+2 +#homepage: https://github.com/stablekernel/open-api-dart +homepage: https://github.com/hpoul/open-api-dart author: stable|kernel environment: From 557f13b088e305454a71fddcd20255ee0a0459d4 Mon Sep 17 00:00:00 2001 From: Herbert Poul Date: Fri, 19 Mar 2021 22:12:09 +0000 Subject: [PATCH 24/30] fix isRequired / isDeprecated --- lib/src/v3/parameter.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/src/v3/parameter.dart b/lib/src/v3/parameter.dart index 5597562..cdcdd54 100644 --- a/lib/src/v3/parameter.dart +++ b/lib/src/v3/parameter.dart @@ -159,8 +159,8 @@ class APIParameter extends APIObject { /// Determines whether this parameter is mandatory. /// /// If the parameter location is "path", this property is REQUIRED and its value MUST be true. Otherwise, the property MAY be included and its default value is false. - bool? get isRequired => - (location == APIParameterLocation.path ? true : _required); + bool get isRequired => + (location == APIParameterLocation.path ? true : _required ?? false); set isRequired(bool? f) { _required = f; @@ -169,7 +169,7 @@ class APIParameter extends APIObject { bool? _required = false; /// Specifies that a parameter is deprecated and SHOULD be transitioned out of usage. - bool? get isDeprecated => _deprecated; + bool get isDeprecated => _deprecated ?? false; set isDeprecated(bool? f) { _deprecated = f; From 962f70bb7e8bdc840c4379e655b28acb131f0aa1 Mon Sep 17 00:00:00 2001 From: Herbert Poul Date: Sat, 20 Mar 2021 00:03:54 +0000 Subject: [PATCH 25/30] fix header parameters, update dependency on codable. --- CHANGELOG.md | 4 ++++ lib/src/v3/parameter.dart | 3 ++- pubspec.yaml | 4 ++-- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7ef1eb1..c4fe816 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 3.0.0+3 + +- fix header parameters, update dependency on codable. + ## 3.0.0+2 - Rename APISchemaObject.isRequired back to required diff --git a/lib/src/v3/parameter.dart b/lib/src/v3/parameter.dart index cdcdd54..493f45b 100644 --- a/lib/src/v3/parameter.dart +++ b/lib/src/v3/parameter.dart @@ -180,6 +180,7 @@ class APIParameter extends APIObject { /// The location of the parameter. /// /// REQUIRED. Possible values are "query", "header", "path" or "cookie". + /// EXCEPT when used as response header 🤦️ APIParameterLocation? location; /// The schema defining the type used for the parameter. @@ -236,7 +237,7 @@ class APIParameter extends APIObject { name = object.decode("name"); description = object.decode("description"); - location = APIParameterLocationCodec.decode(object.decode("in"))!; + location = APIParameterLocationCodec.decode(object.decode("in")); _required = object.decode("required"); _deprecated = object.decode("deprecated"); diff --git a/pubspec.yaml b/pubspec.yaml index 76d8943..b4fc916 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: open_api_forked description: Data structures for OpenAPI (Swagger) specification. Reads and writes JSON specifications. Fork, with a couple of fixes and null safety by @hpoul -version: 3.0.0+2 +version: 3.0.0+3 #homepage: https://github.com/stablekernel/open-api-dart homepage: https://github.com/hpoul/open-api-dart author: stable|kernel @@ -9,7 +9,7 @@ environment: sdk: ">=2.12.0 <3.0.0" dependencies: - codable_forked: ^1.0.0 + codable_forked: ^1.0.0+1 meta: ^1.3.0 dev_dependencies: From 892ed7d6d37985fcac8bcfb498974331d96745ab Mon Sep 17 00:00:00 2001 From: Herbert Poul Date: Mon, 2 Aug 2021 12:00:44 +0200 Subject: [PATCH 26/30] remove many forced null unwrap --- CHANGELOG.md | 4 ++++ lib/src/v2/parameter.dart | 2 +- lib/src/v2/security.dart | 4 ++-- lib/src/v3/callback.dart | 8 ++++---- lib/src/v3/components.dart | 5 +++-- lib/src/v3/operation.dart | 13 +++++-------- lib/src/v3/parameter.dart | 2 +- lib/src/v3/path.dart | 16 ++++++++++------ lib/src/v3/request_body.dart | 5 +++-- lib/src/v3/response.dart | 21 +++++++++++---------- lib/src/v3/security.dart | 4 ++-- pubspec.yaml | 6 +++--- test/v3_test.dart | 6 +++--- 13 files changed, 52 insertions(+), 44 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c4fe816..bd74956 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 3.0.0+4 + +- Remove forced null unwraps. + ## 3.0.0+3 - fix header parameters, update dependency on codable. diff --git a/lib/src/v2/parameter.dart b/lib/src/v2/parameter.dart index c0932f0..2cc41b7 100644 --- a/lib/src/v2/parameter.dart +++ b/lib/src/v2/parameter.dart @@ -82,7 +82,7 @@ class APIParameter extends APIProperty { void encode(KeyedArchive json) { json.encode("name", name); json.encode("description", description); - json.encode("in", APIParameterLocationCodec.encode(location!)); + json.encode("in", APIParameterLocationCodec.encode(location)); json.encode("required", isRequired); if (location == APIParameterLocation.body) { diff --git a/lib/src/v2/security.dart b/lib/src/v2/security.dart index b346f30..5ca14c5 100644 --- a/lib/src/v2/security.dart +++ b/lib/src/v2/security.dart @@ -108,9 +108,9 @@ class APISecurityScheme extends APIObject { /* nothing to do */ } else if (type == "apiKey") { object.encode("name", apiKeyName); - object.encode("in", APIParameterLocationCodec.encode(apiKeyLocation!)); + object.encode("in", APIParameterLocationCodec.encode(apiKeyLocation)); } else if (type == "oauth2") { - object.encode("flow", APISecuritySchemeFlowCodec.encode(oauthFlow!)); + object.encode("flow", APISecuritySchemeFlowCodec.encode(oauthFlow)); object.encode("authorizationUrl", authorizationURL); object.encode("tokenUrl", tokenURL); diff --git a/lib/src/v3/callback.dart b/lib/src/v3/callback.dart index 2f163b7..c980028 100644 --- a/lib/src/v3/callback.dart +++ b/lib/src/v3/callback.dart @@ -5,13 +5,13 @@ import 'package:open_api_forked/src/v3/path.dart'; /// /// Each value in the map is a [APIPath] that describes a set of requests that may be initiated by the API provider and the expected responses. The key value used to identify the callback object is an expression, evaluated at runtime, that identifies a URL to use for the callback operation. class APICallback extends APIObject { - APICallback({this.paths}); - APICallback.empty(); + APICallback({Map? paths}) : paths = paths ?? {}; + APICallback.empty() : paths = {}; /// Callback paths. /// /// The key that identifies the [APIPath] is a runtime expression that can be evaluated in the context of a runtime HTTP request/response to identify the URL to be used for the callback request. A simple example might be $request.body#/url. - Map? paths; + Map paths; void decode(KeyedArchive object) { super.decode(object); @@ -22,7 +22,7 @@ class APICallback extends APIObject { throw ArgumentError( "Invalid specification. Callback contains non-object value."); } - paths![key] = value.decodeObject(key, () => APIPath())!; + paths[key] = value.decodeObject(key, () => APIPath())!; }); } diff --git a/lib/src/v3/components.dart b/lib/src/v3/components.dart index 6e2d4b3..3e6062b 100644 --- a/lib/src/v3/components.dart +++ b/lib/src/v3/components.dart @@ -87,11 +87,12 @@ class APIComponents extends APIObject { } T? resolve(T refObject) { - if (refObject.referenceURI == null) { + final referenceURI = refObject.referenceURI; + if (referenceURI == null) { throw ArgumentError("APIObject is not a reference to a component."); } - return resolveUri(refObject.referenceURI!) as T?; + return resolveUri(referenceURI) as T?; } void decode(KeyedArchive object) { diff --git a/lib/src/v3/operation.dart b/lib/src/v3/operation.dart index b5d4466..10fc64d 100644 --- a/lib/src/v3/operation.dart +++ b/lib/src/v3/operation.dart @@ -93,8 +93,7 @@ class APIOperation extends APIObject { /// If [parameters] is null, invoking this method will set it to a list containing [parameter]. /// Otherwise, [parameter] is added to [parameters]. void addParameter(APIParameter parameter) { - parameters ??= []; - parameters!.add(parameter); + (parameters ??= []).add(parameter); } /// Adds [requirement] to [security]. @@ -102,9 +101,7 @@ class APIOperation extends APIObject { /// If [security] is null, invoking this method will set it to a list containing [requirement]. /// Otherwise, [requirement] is added to [security]. void addSecurityRequirement(APISecurityRequirement requirement) { - security ??= []; - - security!.add(requirement); + (security ??= []).add(requirement); } /// Adds [response] to [responses], merging schemas if necessary. @@ -115,13 +112,13 @@ class APIOperation extends APIObject { /// and headers are added to the list of possible content and headers for the existing response. Descriptions /// of each response are joined together. All headers are marked as optional.. void addResponse(int statusCode, APIResponse response) { - responses ??= {}; + final responses = this.responses ??= {}; final key = "$statusCode"; - final existingResponse = responses![key]; + final existingResponse = responses[key]; if (existingResponse == null) { - responses![key] = response; + responses[key] = response; return; } diff --git a/lib/src/v3/parameter.dart b/lib/src/v3/parameter.dart index 493f45b..e6cb3c1 100644 --- a/lib/src/v3/parameter.dart +++ b/lib/src/v3/parameter.dart @@ -260,7 +260,7 @@ class APIParameter extends APIObject { object.encode("name", name); object.encode("description", description); - object.encode("in", APIParameterLocationCodec.encode(location!)); + object.encode("in", APIParameterLocationCodec.encode(location)); if (location == APIParameterLocation.path) { object.encode("required", true); diff --git a/lib/src/v3/path.dart b/lib/src/v3/path.dart index d20956b..222658b 100644 --- a/lib/src/v3/path.dart +++ b/lib/src/v3/path.dart @@ -6,8 +6,13 @@ import 'package:open_api_forked/src/v3/parameter.dart'; /// /// An [APIPath] MAY be empty, due to ACL constraints. The path itself is still exposed to the documentation viewer but they will not know which operations and parameters are available. class APIPath extends APIObject { - APIPath.empty(); - APIPath({this.summary, this.description, this.parameters, this.operations}); + APIPath.empty() : operations = {}; + APIPath({ + this.summary, + this.description, + this.parameters, + Map? operations, + }) : operations = operations ?? {}; /// An optional, string summary, intended to apply to all operations in this path. String? summary; @@ -25,7 +30,7 @@ class APIPath extends APIObject { /// Definitions of operations on this path. /// /// Keys are lowercased HTTP methods, e.g. get, put, delete, post, etc. - Map? operations; + Map operations; /// Returns true if this path has path parameters [parameterNames]. /// @@ -67,8 +72,7 @@ class APIPath extends APIObject { if (!object.containsKey(methodName)) { return; } - operations ??= {}; - operations![methodName] = + operations[methodName] = object.decodeObject(methodName, () => APIOperation.empty()); }); } @@ -80,7 +84,7 @@ class APIPath extends APIObject { object.encode("description", description); object.encodeObjects("parameters", parameters); - operations!.forEach((opName, op) { + operations.forEach((opName, op) { object.encodeObject(opName.toLowerCase(), op); }); } diff --git a/lib/src/v3/request_body.dart b/lib/src/v3/request_body.dart index b4868b5..9a3e806 100644 --- a/lib/src/v3/request_body.dart +++ b/lib/src/v3/request_body.dart @@ -15,8 +15,9 @@ class APIRequestBody extends APIObject { this.description, bool isRequired = false}) { this.isRequired = isRequired; - this.content = contentTypes.fold({}, (prev, elem) { - prev![elem] = APIMediaType(schema: schema); + this.content = + contentTypes.fold>({}, (prev, elem) { + prev[elem] = APIMediaType(schema: schema); return prev; }); } diff --git a/lib/src/v3/response.dart b/lib/src/v3/response.dart index 4a390e4..589c683 100644 --- a/lib/src/v3/response.dart +++ b/lib/src/v3/response.dart @@ -10,8 +10,8 @@ class APIResponse extends APIObject { APIResponse.schema(this.description, APISchemaObject schema, {Iterable contentTypes: const ["application/json"], this.headers}) { - content = contentTypes.fold({}, (prev, elem) { - prev![elem] = APIMediaType(schema: schema); + content = contentTypes.fold>({}, (prev, elem) { + prev[elem] = APIMediaType(schema: schema); return prev; }); } @@ -39,9 +39,9 @@ class APIResponse extends APIObject { /// If [headers] is null, it is created. If the key does not exist in [headers], [header] is added for the key. /// If the key exists, [header] is not added. (To replace a header, access [headers] directly.) void addHeader(String name, APIHeader? header) { - headers ??= {}; - if (!headers!.containsKey(name)) { - headers![name] = header; + final headers = this.headers ??= {}; + if (!headers.containsKey(name)) { + headers[name] = header; } } @@ -52,18 +52,19 @@ class APIResponse extends APIObject { /// If [content] is null, it is created. If [contentType] does not exist in [content], [bodyObject] is added for [contentType]. /// If [contentType] exists, the [bodyObject] is added the list of possible schemas that were previously added. void addContent(String contentType, APISchemaObject? bodyObject) { - content ??= {}; + final content = this.content ??= {}; final key = contentType; - final existingContent = content![key]; + final existingContent = content[key]; if (existingContent == null) { - content![key] = APIMediaType(schema: bodyObject); + content[key] = APIMediaType(schema: bodyObject); return; } final schema = existingContent.schema; - if (schema?.oneOf != null) { - schema!.oneOf!.add(bodyObject); + final oneOf = schema?.oneOf; + if (oneOf != null) { + oneOf.add(bodyObject); } else { final container = APISchemaObject()..oneOf = [schema, bodyObject]; existingContent.schema = container; diff --git a/lib/src/v3/security.dart b/lib/src/v3/security.dart index 9e6f5c9..a9fae12 100644 --- a/lib/src/v3/security.dart +++ b/lib/src/v3/security.dart @@ -146,7 +146,7 @@ class APISecurityScheme extends APIObject { "APISecurityScheme must have non-null values for: 'type'."); } - object.encode("type", APISecuritySchemeTypeCodec.encode(type!)); + object.encode("type", APISecuritySchemeTypeCodec.encode(type)); object.encode("description", description); switch (type) { @@ -158,7 +158,7 @@ class APISecurityScheme extends APIObject { } object.encode("name", name); - object.encode("in", APIParameterLocationCodec.encode(location!)); + object.encode("in", APIParameterLocationCodec.encode(location)); } break; case APISecuritySchemeType.oauth2: diff --git a/pubspec.yaml b/pubspec.yaml index b4fc916..9ff3703 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: open_api_forked description: Data structures for OpenAPI (Swagger) specification. Reads and writes JSON specifications. Fork, with a couple of fixes and null safety by @hpoul -version: 3.0.0+3 +version: 3.0.0+4 #homepage: https://github.com/stablekernel/open-api-dart homepage: https://github.com/hpoul/open-api-dart author: stable|kernel @@ -10,7 +10,7 @@ environment: dependencies: codable_forked: ^1.0.0+1 - meta: ^1.3.0 + meta: ">=1.3.0 <2.0.0" dev_dependencies: - test: ^1.16.4 + test: ">=1.16.4 <2.0.0" diff --git a/test/v3_test.dart b/test/v3_test.dart index 5b9400b..b3c2958 100644 --- a/test/v3_test.dart +++ b/test/v3_test.dart @@ -136,9 +136,9 @@ void main() { expect(p, isNotNull); expect(p!.description, isNull); - expect(p.operations!.length, 2); + expect(p.operations.length, 2); - final getOp = p.operations!["get"]; + final getOp = p.operations["get"]; final getParams = getOp!.parameters; final getResponses = getOp.responses; expect(getOp.description, contains("10 most recent reversals")); @@ -207,7 +207,7 @@ void main() { }, }, }); - expect(doc.paths!.values.first!.operations!.values.first?.security, + expect(doc.paths!.values.first!.operations.values.first?.security, hasLength(1)); }); }); From ebbda842aed30138baa4b9ee7119b6c2e3ca37ff Mon Sep 17 00:00:00 2001 From: Herbert Poul Date: Mon, 2 Aug 2021 21:27:25 +0200 Subject: [PATCH 27/30] non nullable list elements --- lib/src/v3/schema.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/v3/schema.dart b/lib/src/v3/schema.dart index c24f8f8..2d95ad0 100644 --- a/lib/src/v3/schema.dart +++ b/lib/src/v3/schema.dart @@ -187,7 +187,7 @@ class APISchemaObject extends APIObject { /// /// An object instance is valid against this keyword if its property set /// contains all elements in this keyword's array value. - List? required; + List? required; /// The value of this keyword MUST be an array. This array SHOULD have /// at least one element. Elements in the array SHOULD be unique. From fca695c2a4a44f76f2329218d7f6387356bddf3b Mon Sep 17 00:00:00 2001 From: Herbert Poul Date: Mon, 2 Aug 2021 22:01:31 +0200 Subject: [PATCH 28/30] fix required null error. --- CHANGELOG.md | 2 +- lib/src/v3/request_body.dart | 2 +- pubspec.yaml | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bd74956..4da3d25 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## 3.0.0+4 +## 3.0.0+5 - Remove forced null unwraps. diff --git a/lib/src/v3/request_body.dart b/lib/src/v3/request_body.dart index 9a3e806..a594f47 100644 --- a/lib/src/v3/request_body.dart +++ b/lib/src/v3/request_body.dart @@ -47,7 +47,7 @@ class APIRequestBody extends APIObject { super.decode(object); description = object.decode("description"); - _required = object.decode("required"); + _required = object.decode("required") ?? _required; content = object.decodeObjectMap("content", () => APIMediaType())!; } diff --git a/pubspec.yaml b/pubspec.yaml index 9ff3703..8cc68a7 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,15 +1,15 @@ name: open_api_forked description: Data structures for OpenAPI (Swagger) specification. Reads and writes JSON specifications. Fork, with a couple of fixes and null safety by @hpoul -version: 3.0.0+4 +version: 3.0.0+5 #homepage: https://github.com/stablekernel/open-api-dart homepage: https://github.com/hpoul/open-api-dart -author: stable|kernel +#author: stable|kernel environment: sdk: ">=2.12.0 <3.0.0" dependencies: - codable_forked: ^1.0.0+1 + codable_forked: ^1.0.0+3 meta: ">=1.3.0 <2.0.0" dev_dependencies: From ecd76cd251cb9377658bf82156d226428be9dfaa Mon Sep 17 00:00:00 2001 From: Herbert Poul Date: Mon, 10 Oct 2022 21:21:46 +0200 Subject: [PATCH 29/30] add openIDConnect security scheme type. --- CHANGELOG.md | 4 ++++ lib/src/v3/security.dart | 37 ++++++++++++++++++++++++++----------- pubspec.yaml | 2 +- 3 files changed, 31 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4da3d25..a6c178c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 3.0.0+6 + +- add openIDConnect security scheme type. + ## 3.0.0+5 - Remove forced null unwraps. diff --git a/lib/src/v3/security.dart b/lib/src/v3/security.dart index a9fae12..b275b21 100644 --- a/lib/src/v3/security.dart +++ b/lib/src/v3/security.dart @@ -4,7 +4,13 @@ import 'package:open_api_forked/src/v3/document.dart'; import 'package:open_api_forked/src/v3/operation.dart'; import 'package:open_api_forked/src/v3/parameter.dart'; -enum APISecuritySchemeType { apiKey, http, oauth2, openID } +enum APISecuritySchemeType { + apiKey, + http, + oauth2, + openID, + openIdConnect, +} class APISecuritySchemeTypeCodec { static APISecuritySchemeType? decode(String? type) { @@ -17,6 +23,8 @@ class APISecuritySchemeTypeCodec { return APISecuritySchemeType.oauth2; case "openID": return APISecuritySchemeType.openID; + case "openIdConnect": + return APISecuritySchemeType.openIdConnect; default: return null; } @@ -43,6 +51,7 @@ class APISecuritySchemeTypeCodec { /// Supported schemes are HTTP authentication, an API key (either as a header or as a query parameter), OAuth2's common flows (implicit, password, application and access code) as defined in RFC6749, and OpenID Connect Discovery. class APISecurityScheme extends APIObject { APISecurityScheme(); + APISecurityScheme.empty(); APISecurityScheme.http(this.scheme) : type = APISecuritySchemeType.http; @@ -105,7 +114,7 @@ class APISecurityScheme extends APIObject { void decode(KeyedArchive object) { super.decode(object); - type = APISecuritySchemeTypeCodec.decode(object.decode("type"))!; + type = APISecuritySchemeTypeCodec.decode(object.decode("type")); description = object.decode("description"); switch (type) { @@ -128,13 +137,14 @@ class APISecurityScheme extends APIObject { } break; case APISecuritySchemeType.openID: + case APISecuritySchemeType.openIdConnect: { connectURL = object.decode("openIdConnectUrl"); } break; default: throw ArgumentError( - "APISecurityScheme must have non-null values for: 'type'."); + "APISecurityScheme must have non-null values for: 'type' ${object.decode("type")}."); } } @@ -201,14 +211,18 @@ class APISecurityScheme extends APIObject { /// Allows configuration of the supported OAuth Flows. class APISecuritySchemeOAuth2Flow extends APIObject { APISecuritySchemeOAuth2Flow.empty(); - APISecuritySchemeOAuth2Flow.code( - this.authorizationURL, this.tokenURL, this.refreshURL, this.scopes); - APISecuritySchemeOAuth2Flow.implicit( - this.authorizationURL, this.refreshURL, this.scopes); - APISecuritySchemeOAuth2Flow.password( - this.tokenURL, this.refreshURL, this.scopes); - APISecuritySchemeOAuth2Flow.client( - this.tokenURL, this.refreshURL, this.scopes); + + APISecuritySchemeOAuth2Flow.code(this.authorizationURL, this.tokenURL, + this.refreshURL, this.scopes); + + APISecuritySchemeOAuth2Flow.implicit(this.authorizationURL, this.refreshURL, + this.scopes); + + APISecuritySchemeOAuth2Flow.password(this.tokenURL, this.refreshURL, + this.scopes); + + APISecuritySchemeOAuth2Flow.client(this.tokenURL, this.refreshURL, + this.scopes); /// The authorization URL to be used for this flow. /// @@ -260,6 +274,7 @@ class APISecuritySchemeOAuth2Flow extends APIObject { /// When a list of [APISecurityRequirement] is defined on the [APIDocument] or [APIOperation], only one of [APISecurityRequirement] in the list needs to be satisfied to authorize the request. class APISecurityRequirement extends APIObject { APISecurityRequirement.empty(); + APISecurityRequirement(this.requirements); /// Each name MUST correspond to a security scheme which is declared in [APIComponents.securitySchemes]. diff --git a/pubspec.yaml b/pubspec.yaml index 8cc68a7..5732ed2 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: open_api_forked description: Data structures for OpenAPI (Swagger) specification. Reads and writes JSON specifications. Fork, with a couple of fixes and null safety by @hpoul -version: 3.0.0+5 +version: 3.0.0+6 #homepage: https://github.com/stablekernel/open-api-dart homepage: https://github.com/hpoul/open-api-dart #author: stable|kernel From 85b52ee00434a7e4ec0c5c5f5c226da983244d4f Mon Sep 17 00:00:00 2001 From: Herbert Poul Date: Mon, 29 Jan 2024 11:37:53 +0100 Subject: [PATCH 30/30] only fixed a few warnigns, deprecated lints. --- analysis_options.yaml | 5 +++-- pubspec.yaml | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/analysis_options.yaml b/analysis_options.yaml index 97d4b47..c6b53e5 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -1,3 +1,5 @@ +include: package:lints/recommended.yaml + analyzer: # exclude: # - path/to/excluded/files/** @@ -7,8 +9,7 @@ linter: rules: - cancel_subscriptions - hash_and_equals - - iterable_contains_unrelated_type - - list_remove_unrelated_type + - collection_methods_unrelated_type - test_types_in_equals - unrelated_type_equality_checks - valid_regexps diff --git a/pubspec.yaml b/pubspec.yaml index 5732ed2..0799d57 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -14,3 +14,4 @@ dependencies: dev_dependencies: test: ">=1.16.4 <2.0.0" + lints: ^3.0.0