Skip to content

Commit

Permalink
feat(directive): support GQL directive
Browse files Browse the repository at this point in the history
refactor scalars setter & getter
refactor enum values
  • Loading branch information
hourliert committed Aug 25, 2017
1 parent f9b3b61 commit 034a5eb
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 95 deletions.
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;
}

0 comments on commit 034a5eb

Please sign in to comment.