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
12 changes: 9 additions & 3 deletions example/queries_examples.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class LoginQuery extends Object with Fields implements GQLOperation {
ViewerResolver viewer = new ViewerResolver();

@override
OperationType get type => OperationType.query;
String get type => queryType;

@override
String get name => 'LoginQuery';
Expand All @@ -39,7 +39,7 @@ class AddTestCommentMutation extends Object
AddCommentMutation addComment = new AddCommentMutation();

@override
OperationType get type => OperationType.mutation;
String get type => mutationType;

@override
String get name => 'AddTestCommentMutation';
Expand Down Expand Up @@ -352,11 +352,17 @@ class RepositoriesResolver extends Object
*/

class LoginResolver extends Object
with Scalar<String>, Alias
with Scalar<String>, Alias, Directives
implements GQLField {
@override
String get name => 'login';

@override
String get directive => includeDirective;

@override
String get directiveValue => 'false';

@override
LoginResolver clone() => new LoginResolver()..aliasId = aliasId;
}
Expand Down
29 changes: 13 additions & 16 deletions lib/src/encoder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -50,20 +50,14 @@ class GQLEncoder extends Converter<GQLOperation, String> {

String _encodeOperation(GQLOperation operation) {
final GQLField field = operation;
final rootResolver = _encodeOperationResolvers(operation);
final operationType =
operation.type == OperationType.mutation ? 'mutation' : 'query';
var args = '';
final rootField = _encodeOperationFields(operation);
final args = (field is Arguments) ? '(${field.args})' : '';

if (field is Arguments) {
args = '(${field.args})';
}

return '$operationType ${operation.name} $args { $rootResolver }';
return '${operation.type} ${operation.name} $args { $rootField }';
}

String _encodeOperationResolvers(GQLField operation) =>
_extractFields(operation).map(_encodeResolver).join(' ');
String _encodeOperationFields(GQLField operation) =>
_extractFields(operation).map(_encodeField).join(' ');

String _encodeOperationInlineFragments(GQLField operation) =>
_extractFragments(operation).map(_encodeInlineFragment).join(' ');
Expand All @@ -72,24 +66,27 @@ class GQLEncoder extends Converter<GQLOperation, String> {
_extractNestedFragments(operation).map(_encodeFragment).join('\n');

String _encodeFragment(GQLFragment fragment) {
final rootResolver = _encodeOperationResolvers(fragment);
final rootField = _encodeOperationFields(fragment);
final fragmentsGQL = _encodeNestedOperationFragments(fragment);

return 'fragment ${fragment.name} on ${fragment.onType} { $rootResolver }${fragmentsGQL.isNotEmpty ? fragmentsGQL : ''}';
return 'fragment ${fragment.name} on ${fragment.onType} { $rootField }${fragmentsGQL.isNotEmpty ? fragmentsGQL : ''}';
}

String _encodeResolver(GQLField operation) {
final childrenGQL = _encodeOperationResolvers(operation);
String _encodeField(GQLField operation) {
final childrenGQL = _encodeOperationFields(operation);
final childrenFragment = _encodeOperationInlineFragments(operation);

final alias = (operation is Alias) ? '${operation.alias}: ' : '';
final name = operation.name != null ? '${operation.name} ' : '';
final args = (operation is Arguments) ? '(${operation.args}) ' : '';
final directive = (operation is Directives)
? '@${operation.directive}(if: ${operation.directiveValue}) '
: '';
final fields = (childrenGQL.isNotEmpty || childrenFragment.isNotEmpty)
? '{ $childrenGQL $childrenFragment }'
: '';

return '$alias$name$args$fields';
return '$alias$name$args$directive$fields';
}

String _encodeInlineFragment(GQLFragment fragment) => '...${fragment.name}';
Expand Down
1 change: 1 addition & 0 deletions lib/src/graphql.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ part 'graphql_arguments.dart';
part 'graphql_scalars.dart';
part 'graphql_fields.dart';
part 'graphql_fragments.dart';
part 'graphql_directives.dart';
31 changes: 31 additions & 0 deletions lib/src/graphql_directives.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright Thomas Hourlier. All rights reserved.
// Use of this source code is governed by a MIT-style license
// that can be found in the LICENSE file.

part of graphql_client.definitions;

/// The GQL directive: `include`
const String includeDirective = 'include';

/// The GQL directive: `skip`
const String skipDirective = 'skip';

/// A GraphQL directive.
///
/// It could be applied as a mixin on a [GQLField].
/// Eg.
/// A GQL query with a field using an directive.
/// ```
/// query MyQuery {
/// name @include(if: true)
/// }
/// ```
abstract class Directives implements GQLField {
/// The directive type.
///
/// Should be [includeDirective] or [skipDirective]
String get directive;

/// The GQL directive.
String get directiveValue;
}
23 changes: 10 additions & 13 deletions lib/src/graphql_operations.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,16 @@

part of graphql_client.definitions;

/// A GQL operation type.
enum OperationType {
/// Represents the GQL type: `query`,
query,
/// The GQL type: `query`,
const String queryType = 'query';

/// Represents the GQL type: `mutation`,
mutation,
/// The GQL type: `mutation`,
const String mutationType = 'mutation';

/// Represents the GQL type: `subscription`,
///
/// WARNING: This is not supported.
subscription,
}
/// The GQL type: `subscription`,
///
/// WARNING: This is not supported.
const String subscriptionType = 'subscription';

/// A GQL field.
///
Expand All @@ -39,10 +36,10 @@ abstract class GQLField {

/// A GQL operation.
///
/// This could be whether a: [OperationType.query] or [OperationType.mutation].
/// This could be whether a: [queryType], [mutationType] or [subscriptionType].
abstract class GQLOperation extends GQLField {
/// The query type.
OperationType get type;
String get type;
}

/// A GQL Fragment.
Expand Down
73 changes: 10 additions & 63 deletions lib/src/graphql_scalars.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,8 @@ part of graphql_client.definitions;
/// It could be applied as a mixin on a [GQLField].
/// This mixin should be used on a field that has no nested field and is scalar.
abstract class Scalar<T> implements GQLField {
T _value;

/// Returns the scalar [GQLField] value.
///
/// Throws a [StateError] if the value hasn't been set yet.
T get value {
if (_value == null) {
throw new StateError("This Scalar resolver hasn't been resolved.");
}

return _value;
}

/// Sets the [GQLField] value.
set value(T v) => _value = v;
/// The scalar [GQLField] value.
T value;
}

/// A GQL collection field.
Expand All @@ -32,58 +19,18 @@ abstract class Scalar<T> implements GQLField {
/// This mixin should be used on a field that is a collection
/// (ie. has the GQL List type).
abstract class ScalarCollection<T extends GQLField> implements GQLField {
List<T> _nodes;
List<T> _edges;
int _totalCount;
/// The nodes collection of [GQLField].
List<T> nodes;

/// The edges collection of [GQLField].
List<T> edges;

/// The collection length of [GQLField].
int totalCount;

/// Returns the node [GQLField] that will be used to resolve each list item.
GQLField get nodesResolver => null;

/// Returns the edge [GQLField] that will be used to resolve each list item.
GQLField get edgesResolver => null;

/// Returns the nodes collection of [GQLField].
///
/// Throws a [StateError] if the value hasn't been set yet.
List<T> get nodes {
if (_nodes == null) {
throw new StateError(
"This ScalarCollection resolver hasn't been resolved.");
}

return _nodes;
}

/// Sets the nodes collection of [GQLField].
set nodes(List<T> v) => _nodes = v;

/// Returns the edges collection of [GQLField].
///
/// Throws a [StateError] if the value hasn't been set yet.
List<T> get edges {
if (_edges == null) {
throw new StateError(
"This ScalarCollection resolver hasn't been resolved.");
}

return _edges;
}

/// Sets the edges collection of [GQLField].
set edges(List<T> v) => _edges = v;

/// Returns the number of resolved items.
///
/// Throws a [StateError] if the value hasn't been set yet.
int get totalCount {
if (_totalCount == null) {
throw new StateError(
"This ScalarCollection resolver hasn't been resolved.");
}

return _totalCount;
}

/// Sets the number of resolved items.
set totalCount(int v) => _totalCount = v;
}