Skip to content

Commit 81764ab

Browse files
authored
Merge pull request #8 from hourliert/feat/support_directives
feat(directive): support GQL directive
2 parents f9b3b61 + 034a5eb commit 81764ab

6 files changed

+74
-95
lines changed

example/queries_examples.dart

+9-3
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ class LoginQuery extends Object with Fields implements GQLOperation {
2121
ViewerResolver viewer = new ViewerResolver();
2222

2323
@override
24-
OperationType get type => OperationType.query;
24+
String get type => queryType;
2525

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

4141
@override
42-
OperationType get type => OperationType.mutation;
42+
String get type => mutationType;
4343

4444
@override
4545
String get name => 'AddTestCommentMutation';
@@ -352,11 +352,17 @@ class RepositoriesResolver extends Object
352352
*/
353353

354354
class LoginResolver extends Object
355-
with Scalar<String>, Alias
355+
with Scalar<String>, Alias, Directives
356356
implements GQLField {
357357
@override
358358
String get name => 'login';
359359

360+
@override
361+
String get directive => includeDirective;
362+
363+
@override
364+
String get directiveValue => 'false';
365+
360366
@override
361367
LoginResolver clone() => new LoginResolver()..aliasId = aliasId;
362368
}

lib/src/encoder.dart

+13-16
Original file line numberDiff line numberDiff line change
@@ -50,20 +50,14 @@ class GQLEncoder extends Converter<GQLOperation, String> {
5050

5151
String _encodeOperation(GQLOperation operation) {
5252
final GQLField field = operation;
53-
final rootResolver = _encodeOperationResolvers(operation);
54-
final operationType =
55-
operation.type == OperationType.mutation ? 'mutation' : 'query';
56-
var args = '';
53+
final rootField = _encodeOperationFields(operation);
54+
final args = (field is Arguments) ? '(${field.args})' : '';
5755

58-
if (field is Arguments) {
59-
args = '(${field.args})';
60-
}
61-
62-
return '$operationType ${operation.name} $args { $rootResolver }';
56+
return '${operation.type} ${operation.name} $args { $rootField }';
6357
}
6458

65-
String _encodeOperationResolvers(GQLField operation) =>
66-
_extractFields(operation).map(_encodeResolver).join(' ');
59+
String _encodeOperationFields(GQLField operation) =>
60+
_extractFields(operation).map(_encodeField).join(' ');
6761

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

7468
String _encodeFragment(GQLFragment fragment) {
75-
final rootResolver = _encodeOperationResolvers(fragment);
69+
final rootField = _encodeOperationFields(fragment);
7670
final fragmentsGQL = _encodeNestedOperationFragments(fragment);
7771

78-
return 'fragment ${fragment.name} on ${fragment.onType} { $rootResolver }${fragmentsGQL.isNotEmpty ? fragmentsGQL : ''}';
72+
return 'fragment ${fragment.name} on ${fragment.onType} { $rootField }${fragmentsGQL.isNotEmpty ? fragmentsGQL : ''}';
7973
}
8074

81-
String _encodeResolver(GQLField operation) {
82-
final childrenGQL = _encodeOperationResolvers(operation);
75+
String _encodeField(GQLField operation) {
76+
final childrenGQL = _encodeOperationFields(operation);
8377
final childrenFragment = _encodeOperationInlineFragments(operation);
8478

8579
final alias = (operation is Alias) ? '${operation.alias}: ' : '';
8680
final name = operation.name != null ? '${operation.name} ' : '';
8781
final args = (operation is Arguments) ? '(${operation.args}) ' : '';
82+
final directive = (operation is Directives)
83+
? '@${operation.directive}(if: ${operation.directiveValue}) '
84+
: '';
8885
final fields = (childrenGQL.isNotEmpty || childrenFragment.isNotEmpty)
8986
? '{ $childrenGQL $childrenFragment }'
9087
: '';
9188

92-
return '$alias$name$args$fields';
89+
return '$alias$name$args$directive$fields';
9390
}
9491

9592
String _encodeInlineFragment(GQLFragment fragment) => '...${fragment.name}';

lib/src/graphql.dart

+1
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@ part 'graphql_arguments.dart';
1212
part 'graphql_scalars.dart';
1313
part 'graphql_fields.dart';
1414
part 'graphql_fragments.dart';
15+
part 'graphql_directives.dart';

lib/src/graphql_directives.dart

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright Thomas Hourlier. All rights reserved.
2+
// Use of this source code is governed by a MIT-style license
3+
// that can be found in the LICENSE file.
4+
5+
part of graphql_client.definitions;
6+
7+
/// The GQL directive: `include`
8+
const String includeDirective = 'include';
9+
10+
/// The GQL directive: `skip`
11+
const String skipDirective = 'skip';
12+
13+
/// A GraphQL directive.
14+
///
15+
/// It could be applied as a mixin on a [GQLField].
16+
/// Eg.
17+
/// A GQL query with a field using an directive.
18+
/// ```
19+
/// query MyQuery {
20+
/// name @include(if: true)
21+
/// }
22+
/// ```
23+
abstract class Directives implements GQLField {
24+
/// The directive type.
25+
///
26+
/// Should be [includeDirective] or [skipDirective]
27+
String get directive;
28+
29+
/// The GQL directive.
30+
String get directiveValue;
31+
}

lib/src/graphql_operations.dart

+10-13
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,16 @@
44

55
part of graphql_client.definitions;
66

7-
/// A GQL operation type.
8-
enum OperationType {
9-
/// Represents the GQL type: `query`,
10-
query,
7+
/// The GQL type: `query`,
8+
const String queryType = 'query';
119

12-
/// Represents the GQL type: `mutation`,
13-
mutation,
10+
/// The GQL type: `mutation`,
11+
const String mutationType = 'mutation';
1412

15-
/// Represents the GQL type: `subscription`,
16-
///
17-
/// WARNING: This is not supported.
18-
subscription,
19-
}
13+
/// The GQL type: `subscription`,
14+
///
15+
/// WARNING: This is not supported.
16+
const String subscriptionType = 'subscription';
2017

2118
/// A GQL field.
2219
///
@@ -39,10 +36,10 @@ abstract class GQLField {
3936

4037
/// A GQL operation.
4138
///
42-
/// This could be whether a: [OperationType.query] or [OperationType.mutation].
39+
/// This could be whether a: [queryType], [mutationType] or [subscriptionType].
4340
abstract class GQLOperation extends GQLField {
4441
/// The query type.
45-
OperationType get type;
42+
String get type;
4643
}
4744

4845
/// A GQL Fragment.

lib/src/graphql_scalars.dart

+10-63
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,8 @@ part of graphql_client.definitions;
99
/// It could be applied as a mixin on a [GQLField].
1010
/// This mixin should be used on a field that has no nested field and is scalar.
1111
abstract class Scalar<T> implements GQLField {
12-
T _value;
13-
14-
/// Returns the scalar [GQLField] value.
15-
///
16-
/// Throws a [StateError] if the value hasn't been set yet.
17-
T get value {
18-
if (_value == null) {
19-
throw new StateError("This Scalar resolver hasn't been resolved.");
20-
}
21-
22-
return _value;
23-
}
24-
25-
/// Sets the [GQLField] value.
26-
set value(T v) => _value = v;
12+
/// The scalar [GQLField] value.
13+
T value;
2714
}
2815

2916
/// A GQL collection field.
@@ -32,58 +19,18 @@ abstract class Scalar<T> implements GQLField {
3219
/// This mixin should be used on a field that is a collection
3320
/// (ie. has the GQL List type).
3421
abstract class ScalarCollection<T extends GQLField> implements GQLField {
35-
List<T> _nodes;
36-
List<T> _edges;
37-
int _totalCount;
22+
/// The nodes collection of [GQLField].
23+
List<T> nodes;
24+
25+
/// The edges collection of [GQLField].
26+
List<T> edges;
27+
28+
/// The collection length of [GQLField].
29+
int totalCount;
3830

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

4234
/// Returns the edge [GQLField] that will be used to resolve each list item.
4335
GQLField get edgesResolver => null;
44-
45-
/// Returns the nodes collection of [GQLField].
46-
///
47-
/// Throws a [StateError] if the value hasn't been set yet.
48-
List<T> get nodes {
49-
if (_nodes == null) {
50-
throw new StateError(
51-
"This ScalarCollection resolver hasn't been resolved.");
52-
}
53-
54-
return _nodes;
55-
}
56-
57-
/// Sets the nodes collection of [GQLField].
58-
set nodes(List<T> v) => _nodes = v;
59-
60-
/// Returns the edges collection of [GQLField].
61-
///
62-
/// Throws a [StateError] if the value hasn't been set yet.
63-
List<T> get edges {
64-
if (_edges == null) {
65-
throw new StateError(
66-
"This ScalarCollection resolver hasn't been resolved.");
67-
}
68-
69-
return _edges;
70-
}
71-
72-
/// Sets the edges collection of [GQLField].
73-
set edges(List<T> v) => _edges = v;
74-
75-
/// Returns the number of resolved items.
76-
///
77-
/// Throws a [StateError] if the value hasn't been set yet.
78-
int get totalCount {
79-
if (_totalCount == null) {
80-
throw new StateError(
81-
"This ScalarCollection resolver hasn't been resolved.");
82-
}
83-
84-
return _totalCount;
85-
}
86-
87-
/// Sets the number of resolved items.
88-
set totalCount(int v) => _totalCount = v;
8936
}

0 commit comments

Comments
 (0)