Skip to content

Nullsafety #7

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
language: dart
dart:
- stable
- beta

before_script:
- mkdir test/specs
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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());
```
Expand Down
9 changes: 6 additions & 3 deletions lib/src/object.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,17 @@ 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(", ")}");
}

extensions.forEach((key, value) {
object.encode(key, value);
});
}
}
}
42 changes: 22 additions & 20 deletions lib/src/v2/document.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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<APITag> tags = [];
List<String> schemes = [];
List<String> consumes = [];
List<String> produces = [];
List<Map<String, List<String>>> security = [];
List<APITag?>? tags = [];
List<String>? schemes = [];
List<String>? consumes = [];
List<String>? produces = [];
List<Map<String, List<String?>>?> security = [];

Map<String, APIPath> paths = {};
Map<String, APIResponse> responses = {};
Map<String, APIParameter> parameters = {};
Map<String, APISchemaObject> definitions = {};
Map<String, APISecurityScheme> securityDefinitions = {};
Map<String, APIPath?>? paths = {};
Map<String, APIResponse?>? responses = {};
Map<String, APIParameter?>? parameters = {};
Map<String, APISchemaObject?>? definitions = {};
Map<String, APISecurityScheme?>? securityDefinitions = {};

Map<String, dynamic> asMap() {
return KeyedArchive.archive(this, allowReferences: true);
Expand All @@ -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) {
Expand Down
6 changes: 3 additions & 3 deletions lib/src/v2/header.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}
}

Expand Down
18 changes: 9 additions & 9 deletions lib/src/v2/metadata.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,20 @@ class APIInfo extends APIObject {
APIInfo();

String title = "API";
String description = "Description";
String version = "1.0";
String termsOfServiceURL = "";
APIContact contact = new APIContact();
APILicense license = new APILicense();
String? description = "Description";
String? version = "1.0";
String? termsOfServiceURL = "";
APIContact? contact = APIContact();
APILicense? license = APILicense();

void decode(KeyedArchive object) {
super.decode(object);

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");
}

Expand Down Expand Up @@ -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);
Expand Down
24 changes: 12 additions & 12 deletions lib/src/v2/operation.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,18 @@ class APIOperation extends APIObject {
"security": cast.List(cast.Map(cast.String, cast.List(cast.String))),
};

String summary = "";
String description = "";
String id;
String? summary = "";
String? description = "";
String? id;
bool deprecated = false;

List<String> tags = [];
List<String> schemes = [];
List<String> consumes = [];
List<String> produces = [];
List<APIParameter> parameters = [];
List<Map<String, List<String>>> security = [];
Map<String, APIResponse> responses = {};
List<String?>? tags = [];
List<String?>? schemes = [];
List<String?>? consumes = [];
List<String?>? produces = [];
List<APIParameter?>? parameters = [];
List<Map<String, List<String>>?>? security = [];
Map<String, APIResponse?>? responses = {};

void decode(KeyedArchive object) {
super.decode(object);
Expand All @@ -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");
}
Expand Down
35 changes: 18 additions & 17 deletions lib/src/v2/parameter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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";
Expand All @@ -36,53 +36,54 @@ class APIParameterLocationCodec {
return "formData";
case APIParameterLocation.body:
return "body";
default:
return null;
}
return null;
}
}

/// Represents a parameter in the OpenAPI specification.
class APIParameter extends APIProperty {
APIParameter();

String name;
String description;
bool required = false;
APIParameterLocation location;
String? name;
String? description;
bool isRequired = false;
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");
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") ?? false;
}

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());
}
}
}

void encode(KeyedArchive json) {
json.encode("name", name);
json.encode("description", description);
json.encode("in", APIParameterLocationCodec.encode(location));
json.encode("required", required);
json.encode("in", APIParameterLocationCodec.encode(location!));
json.encode("required", isRequired);

if (location == APIParameterLocation.body) {
json.encodeObject("schema", schema);
Expand Down
8 changes: 4 additions & 4 deletions lib/src/v2/path.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import 'package:open_api/src/v2/parameter.dart';
class APIPath extends APIObject {
APIPath();

List<APIParameter> parameters = [];
Map<String, APIOperation> operations = {};
List<APIParameter?> parameters = [];
Map<String, APIOperation?> operations = {};

void decode(KeyedArchive object) {
super.decode(object);
Expand All @@ -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());
}
});
}
Expand Down
41 changes: 21 additions & 20 deletions lib/src/v2/property.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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";
Expand All @@ -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<dynamic> enumerated;
num? maximum;
bool? exclusiveMaximum;
num? minimum;
bool? exclusiveMinimum;
int? maxLength;
int? minLength;
String? pattern;
int? maxItems;
int? minItems;
bool? uniqueItems;
num? multipleOf;
List<dynamic>? enumerated;

APISchemaRepresentation get representation {
if (type == APIType.array) {
Expand Down
Loading