Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
include: package:pedantic/analysis_options.yaml
3 changes: 2 additions & 1 deletion example/cars_server.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import 'dart:io';
import 'package:json_api/server.dart';
import 'package:json_api/src/server/server_document_factory.dart';
import 'package:json_api/url_design.dart';
import 'package:pedantic/pedantic.dart';

import 'cars_server/controller.dart';
import 'cars_server/dao.dart';
Expand Down Expand Up @@ -63,6 +64,6 @@ Future<HttpServer> createServer(InternetAddress addr, int port) async {
ServerDocumentFactory(urlDesign, pagination: pagination);
final jsonApiServer = JsonApiServer(urlDesign, controller, documentFactory);

httpServer.forEach(jsonApiServer.serve);
unawaited(httpServer.forEach(jsonApiServer.serve));
return httpServer;
}
2 changes: 1 addition & 1 deletion example/cars_server/controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,6 @@ class CarsController implements JsonApiController {
return resource;
}

Map<T, R> _filter<T, R>(Map<T, R> map, bool f(T t)) =>
Map<T, R> _filter<T, R>(Map<T, R> map, bool Function(T t) f) =>
{...map}..removeWhere((k, _) => !f(k));
}
11 changes: 10 additions & 1 deletion example/cars_server/dao.dart
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,14 @@ abstract class DAO<T> {
}

class ModelDAO extends DAO<Model> {
@override
Resource toResource(Model _) =>
Resource('models', _.id, attributes: {'name': _.name});

@override
void insert(Model model) => _collection[model.id] = model;

@override
Model create(Resource r) {
return Model(r.id)..name = r.attributes['name'];
}
Expand All @@ -66,17 +69,21 @@ class ModelDAO extends DAO<Model> {
}

class CityDAO extends DAO<City> {
@override
Resource toResource(City _) =>
Resource('cities', _.id, attributes: {'name': _.name});

@override
void insert(City city) => _collection[city.id] = city;

@override
City create(Resource r) {
return City(r.id)..name = r.attributes['name'];
}
}

class CompanyDAO extends DAO<Company> {
@override
Resource toResource(Company company) =>
Resource('companies', company.id, attributes: {
'name': company.name,
Expand All @@ -90,11 +97,13 @@ class CompanyDAO extends DAO<Company> {
'models': company.models.map((_) => Identifier('models', _)).toList()
});

@override
void insert(Company company) {
company.updatedAt = DateTime.now();
_collection[company.id] = company;
}

@override
Company create(Resource r) {
return Company(r.id)
..name = r.attributes['name']
Expand All @@ -104,7 +113,7 @@ class CompanyDAO extends DAO<Company> {
@override
int deleteById(String id) {
final company = fetchById(id);
int deps = company.headquarters == null ? 0 : 1;
var deps = company.headquarters == null ? 0 : 1;
deps += company.models.length;
_collection.remove(id);
return deps;
Expand Down
2 changes: 1 addition & 1 deletion example/cars_server/job_queue.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ class Job {
Resource resource;

Job(Future<Resource> create) : id = Uuid().v4() {
create.then((_) => this.resource = _);
create.then((_) => resource = _);
}
}
2 changes: 1 addition & 1 deletion example/cars_server/model.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
class Company {
final String id;
String headquarters;
final models = Set<String>();
final models = <String>{};

/// Company name
String name;
Expand Down
7 changes: 4 additions & 3 deletions lib/src/client/json_api_client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ class JsonApiClient {
..body = json.encode(doc);

Future<Response<D>> _call<D extends PrimaryData>(
http.Request request, D decodePrimaryData(Object _)) async {
http.Request request, D Function(Object _) decodePrimaryData) async {
final response =
await http.Response.fromStream(await httpClient.send(request));
_onHttpCall(request, response);
Expand All @@ -217,6 +217,7 @@ class JsonApiClient {

/// Defines the hook which gets called when the HTTP response is received from
/// the HTTP Client.
typedef void OnHttpCall(http.Request request, http.Response response);
typedef OnHttpCall = void Function(
http.Request request, http.Response response);

_doNothing(http.Request request, http.Response response) {}
void _doNothing(http.Request request, http.Response response) {}
2 changes: 1 addition & 1 deletion lib/src/document/api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class Api {
final Map<String, Object> meta;

Api({this.version, Map<String, Object> meta})
: this.meta = meta == null ? null : Map.unmodifiable(meta);
: meta = meta == null ? null : Map.unmodifiable(meta);

static Api fromJson(Object json) {
if (json is Map) {
Expand Down
18 changes: 9 additions & 9 deletions lib/src/document/document.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,27 +20,27 @@ class Document<Data extends PrimaryData> {

/// Create a document with primary data
Document(this.data, {Map<String, Object> meta, this.api})
: this.errors = null,
this.meta = (meta == null) ? null : Map.unmodifiable(meta);
: errors = null,
meta = (meta == null) ? null : Map.unmodifiable(meta);

/// Create a document with errors (no primary data)
Document.error(Iterable<JsonApiError> errors,
{Map<String, Object> meta, this.api})
: this.data = null,
this.meta = (meta == null) ? null : Map.unmodifiable(meta),
this.errors = List.unmodifiable(errors);
: data = null,
meta = (meta == null) ? null : Map.unmodifiable(meta),
errors = List.unmodifiable(errors);

/// Create an empty document (no primary data and no errors)
Document.empty(Map<String, Object> meta, {this.api})
: this.data = null,
this.meta = (meta == null) ? null : Map.unmodifiable(meta),
this.errors = null {
: data = null,
meta = (meta == null) ? null : Map.unmodifiable(meta),
errors = null {
ArgumentError.checkNotNull(meta, 'meta');
}

/// Reconstructs a document with the specified primary data
static Document<Data> fromJson<Data extends PrimaryData>(
Object json, Data primaryData(Object json)) {
Object json, Data Function(Object json) primaryData) {
if (json is Map) {
Api api;
if (json.containsKey('jsonapi')) {
Expand Down
3 changes: 2 additions & 1 deletion lib/src/document/identifier.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,6 @@ class Identifier {
other.type == type &&
other.id == id;

String toString() => "Identifier($type:$id)";
@override
String toString() => 'Identifier($type:$id)';
}
2 changes: 1 addition & 1 deletion lib/src/document/identifier_object.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class IdentifierObject {
/// Creates an instance of [IdentifierObject].
/// [type] and [id] can not be null.
IdentifierObject(this.type, this.id, {Map<String, Object> meta})
: this.meta = (meta == null) ? null : Map.unmodifiable(meta) {
: meta = (meta == null) ? null : Map.unmodifiable(meta) {
ArgumentError.checkNotNull(type);
ArgumentError.checkNotNull(id);
}
Expand Down
5 changes: 3 additions & 2 deletions lib/src/document/link.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class Link {
throw DecodingException('Can not decode links map from $json');
}

toJson() => uri.toString();
Object toJson() => uri.toString();

@override
String toString() => uri.toString();
Expand All @@ -49,7 +49,8 @@ class LinkObject extends Link {
throw DecodingException('Can not decode LinkObject from $json');
}

toJson() => {
@override
Object toJson() => {
'href': uri.toString(),
if (meta != null) ...{'meta': meta}
};
Expand Down
4 changes: 2 additions & 2 deletions lib/src/document/primary_data.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ abstract class PrimaryData {
final Map<String, Link> links;

PrimaryData({Iterable<ResourceObject> included, Map<String, Link> links})
: this.included = (included == null) ? null : List.unmodifiable(included),
this.links = (links == null) ? null : Map.unmodifiable(links);
: included = (included == null) ? null : List.unmodifiable(included),
links = (links == null) ? null : Map.unmodifiable(links);

/// The `self` link. May be null.
Link get self => (links ?? {})['self'];
Expand Down
3 changes: 3 additions & 0 deletions lib/src/document/relationship.dart
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ class Relationship extends PrimaryData {
}

/// Top-level JSON object
@override
Map<String, Object> toJson() => {
...super.toJson(),
if (links != null) ...{'links': links}
Expand Down Expand Up @@ -85,6 +86,7 @@ class ToOne extends Relationship {
throw DecodingException('Can not decode ToOne from $json');
}

@override
Map<String, Object> toJson() => {
...super.toJson(),
...{'data': linkage}
Expand Down Expand Up @@ -124,6 +126,7 @@ class ToMany extends Relationship {
throw DecodingException('Can not decode ToMany from $json');
}

@override
Map<String, Object> toJson() => {
...super.toJson(),
'data': linkage,
Expand Down
4 changes: 2 additions & 2 deletions lib/src/nullable.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
_Fun<U, V> nullable<V, U>(U f(V v)) => (v) => v == null ? null : f(v);
_Fun<U, V> nullable<V, U>(U Function(V v) f) => (v) => v == null ? null : f(v);

typedef U _Fun<U, V>(V v);
typedef _Fun<U, V> = U Function(V v);
1 change: 1 addition & 0 deletions lib/src/query/include.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class Include extends QueryParameters with IterableMixin<String> {
static Include fromUri(Uri uri) =>
Include((uri.queryParameters['include'] ?? '').split(','));

@override
Iterator<String> get iterator => _resources.iterator;

final List<String> _resources;
Expand Down
2 changes: 1 addition & 1 deletion lib/src/server/http_method.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
class HttpMethod {
final String _name;

HttpMethod(String name) : this._name = name.toUpperCase();
HttpMethod(String name) : _name = name.toUpperCase();

bool isPost() => _name == 'POST';

Expand Down
1 change: 1 addition & 0 deletions lib/src/server/response/error_response.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ class ErrorResponse extends JsonApiResponse {

const ErrorResponse(int status, this.errors) : super(status);

@override
Document buildDocument(ServerDocumentFactory builder, Uri self) =>
builder.makeErrorDocument(errors);

Expand Down
2 changes: 1 addition & 1 deletion lib/src/server/routing/route_factory.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ class RouteFactory implements MatchCase<Route> {
const RouteFactory();

@override
unmatched() => InvalidRoute();
Route unmatched() => InvalidRoute();

@override
Route collection(String type) => CollectionRoute(type);
Expand Down
4 changes: 2 additions & 2 deletions lib/src/server/server_document_factory.dart
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ class ServerDocumentFactory {
ToMany(
identifiers.map(IdentifierObject.fromIdentifier),
links: {
"self": Link(self),
"related": Link(_url.related(type, id, relationship))
'self': Link(self),
'related': Link(_url.related(type, id, relationship))
},
),
api: _api);
Expand Down
4 changes: 4 additions & 0 deletions lib/src/url_design/path_based_url_design.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class PathBasedUrlDesign implements UrlDesign {
PathBasedUrlDesign(this.base);

/// Returns a URL for the primary resource collection of type [type]
@override
Uri collection(
String type,
) =>
Expand All @@ -19,16 +20,19 @@ class PathBasedUrlDesign implements UrlDesign {
/// Returns a URL for the related resource/collection.
/// The [type] and [id] identify the primary resource and the [relationship]
/// is the relationship name.
@override
Uri related(String type, String id, String relationship) =>
_appendToBase([type, id, relationship]);

/// Returns a URL for the relationship itself.
/// The [type] and [id] identify the primary resource and the [relationship]
/// is the relationship name.
@override
Uri relationship(String type, String id, String relationship) =>
_appendToBase([type, id, _relationships, relationship]);

/// Returns a URL for the primary resource of type [type] with id [id]
@override
Uri resource(String type, String id) => _appendToBase([type, id]);

@override
Expand Down
3 changes: 2 additions & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: json_api
version: 3.1.0
version: 3.1.0+1
homepage: https://github.com/f3ath/json-api-dart
description: JSON:API Client for Flutter, Web and VM. Supports JSON:API v1.0 (http://jsonapi.org)
environment:
Expand All @@ -8,6 +8,7 @@ dependencies:
http: ^0.12.0
collection: ^1.14.11
dev_dependencies:
pedantic: ^1.0.0
test: ^1.9.2
json_matcher: ^0.2.3
stream_channel: ^2.0.0
Expand Down
4 changes: 2 additions & 2 deletions test/functional/test_server.dart
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import 'dart:io';

import "package:stream_channel/stream_channel.dart";
import 'package:stream_channel/stream_channel.dart';

import '../../example/cars_server.dart';

hybridMain(StreamChannel channel, Object message) async {
void hybridMain(StreamChannel channel, Object message) async {
final port = 8080;
await createServer(InternetAddress.loopbackIPv4, port);
channel.sink.add(port);
Expand Down
6 changes: 3 additions & 3 deletions test/unit/document/api_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import 'package:test/test.dart';
void main() {
test('Api can be json-encoded', () {
final api = Api.fromJson(
json.decode(json.encode(Api(version: "1.0", meta: {"foo": "bar"}))));
expect("1.0", api.version);
expect("bar", api.meta["foo"]);
json.decode(json.encode(Api(version: '1.0', meta: {'foo': 'bar'}))));
expect('1.0', api.version);
expect('bar', api.meta['foo']);
});

test('Empty/null properties are not encoded', () {
Expand Down
Loading