diff --git a/example/queries_examples.dart b/example/queries_examples.dart index dd449d7..896e2be 100644 --- a/example/queries_examples.dart +++ b/example/queries_examples.dart @@ -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'; @@ -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'; @@ -352,11 +352,17 @@ class RepositoriesResolver extends Object */ class LoginResolver extends Object - with Scalar, Alias + with Scalar, 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; } diff --git a/lib/src/encoder.dart b/lib/src/encoder.dart index 3ec9490..a781974 100644 --- a/lib/src/encoder.dart +++ b/lib/src/encoder.dart @@ -50,20 +50,14 @@ class GQLEncoder extends Converter { 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(' '); @@ -72,24 +66,27 @@ class GQLEncoder extends Converter { _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}'; diff --git a/lib/src/graphql.dart b/lib/src/graphql.dart index 0bdae89..cd3ed75 100644 --- a/lib/src/graphql.dart +++ b/lib/src/graphql.dart @@ -12,3 +12,4 @@ part 'graphql_arguments.dart'; part 'graphql_scalars.dart'; part 'graphql_fields.dart'; part 'graphql_fragments.dart'; +part 'graphql_directives.dart'; diff --git a/lib/src/graphql_directives.dart b/lib/src/graphql_directives.dart new file mode 100644 index 0000000..73cae2d --- /dev/null +++ b/lib/src/graphql_directives.dart @@ -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; +} diff --git a/lib/src/graphql_operations.dart b/lib/src/graphql_operations.dart index 51a95c5..ad747ae 100644 --- a/lib/src/graphql_operations.dart +++ b/lib/src/graphql_operations.dart @@ -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. /// @@ -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. diff --git a/lib/src/graphql_scalars.dart b/lib/src/graphql_scalars.dart index 028114f..4c0ce33 100644 --- a/lib/src/graphql_scalars.dart +++ b/lib/src/graphql_scalars.dart @@ -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 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. @@ -32,58 +19,18 @@ abstract class Scalar implements GQLField { /// This mixin should be used on a field that is a collection /// (ie. has the GQL List type). abstract class ScalarCollection implements GQLField { - List _nodes; - List _edges; - int _totalCount; + /// The nodes collection of [GQLField]. + List nodes; + + /// The edges collection of [GQLField]. + List 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 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 v) => _nodes = v; - - /// Returns the edges collection of [GQLField]. - /// - /// Throws a [StateError] if the value hasn't been set yet. - List 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 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; }