├── .gitignore
├── .idea
├── graphql_parser.iml
├── modules.xml
├── runConfigurations
│ ├── main_dart.xml
│ ├── objects_in_equality_test_dart.xml
│ ├── server_dart.xml
│ ├── tests_in_comment_test_dart.xml
│ ├── tests_in_graphql_parser.xml
│ ├── tests_in_graphql_schema.xml
│ ├── tests_in_mirrors_test_dart.xml
│ ├── tests_in_query_test_dart.xml
│ ├── tests_in_validation_test_dart.xml
│ └── tests_in_value_test_dart.xml
└── vcs.xml
├── .travis.yml
├── LICENSE
├── README.md
├── angel_graphql
├── .gitignore
├── CHANGELOG.md
├── LICENSE
├── README.md
├── analysis_options.yaml
├── angel_graphql.iml
├── example
│ ├── main.dart
│ └── subscription.dart
├── lib
│ ├── angel_graphql.dart
│ └── src
│ │ ├── graphiql.dart
│ │ ├── graphql_http.dart
│ │ ├── graphql_ws.dart
│ │ └── resolvers.dart
├── mono_pkg.yaml
└── pubspec.yaml
├── data_loader
├── .gitignore
├── CHANGELOG.md
├── LICENSE
├── README.md
├── analysis_options.yaml
├── example
│ └── main.dart
├── lib
│ └── data_loader.dart
├── mono_pkg.yaml
├── pubspec.yaml
└── test
│ └── all_test.dart
├── example_star_wars
├── .gitignore
├── LICENSE
├── analysis_options.yaml
├── bin
│ └── server.dart
├── example_star_wars.iml
├── lib
│ ├── src
│ │ ├── models
│ │ │ ├── character.dart
│ │ │ ├── character.g.dart
│ │ │ ├── droid.dart
│ │ │ ├── droid.g.dart
│ │ │ ├── episode.dart
│ │ │ ├── episode.g.dart
│ │ │ ├── human.dart
│ │ │ ├── human.g.dart
│ │ │ ├── models.dart
│ │ │ ├── starship.dart
│ │ │ └── starship.g.dart
│ │ └── pretty_logging.dart
│ └── star_wars.dart
├── mono_pkg.yaml
└── pubspec.yaml
├── graphql.iml
├── graphql_generator
├── .gitignore
├── CHANGELOG.md
├── LICENSE
├── README.md
├── analysis_options.yaml
├── build.yaml
├── example
│ ├── main.dart
│ └── main.g.dart
├── lib
│ └── graphql_generator.dart
├── mono_pkg.yaml
└── pubspec.yaml
├── graphql_parser
├── .gitignore
├── CHANGELOG.md
├── LICENSE
├── README.md
├── analysis_options.yaml
├── example
│ └── example.dart
├── graphql_parser.iml
├── lib
│ ├── graphql_parser.dart
│ └── src
│ │ └── language
│ │ ├── ast
│ │ ├── alias.dart
│ │ ├── argument.dart
│ │ ├── array_value.dart
│ │ ├── ast.dart
│ │ ├── boolean_value.dart
│ │ ├── default_value.dart
│ │ ├── definition.dart
│ │ ├── deprecated_value.dart
│ │ ├── directive.dart
│ │ ├── document.dart
│ │ ├── field.dart
│ │ ├── field_name.dart
│ │ ├── fragment_definition.dart
│ │ ├── fragment_spread.dart
│ │ ├── inline_fragment.dart
│ │ ├── input_value.dart
│ │ ├── list_type.dart
│ │ ├── misc_value.dart
│ │ ├── node.dart
│ │ ├── number_value.dart
│ │ ├── operation_definition.dart
│ │ ├── selection.dart
│ │ ├── selection_set.dart
│ │ ├── string_value.dart
│ │ ├── type.dart
│ │ ├── type_condition.dart
│ │ ├── type_name.dart
│ │ ├── variable.dart
│ │ ├── variable_definition.dart
│ │ └── variable_definitions.dart
│ │ ├── language.dart
│ │ ├── lexer.dart
│ │ ├── parser.dart
│ │ ├── syntax_error.dart
│ │ ├── token.dart
│ │ └── token_type.dart
├── mono_pkg.yaml
├── pubspec.yaml
└── test
│ ├── argument_test.dart
│ ├── comment_test.dart
│ ├── common.dart
│ ├── directive_test.dart
│ ├── document_test.dart
│ ├── field_test.dart
│ ├── fragment_spread_test.dart
│ ├── inline_fragment_test.dart
│ ├── issue23_test.dart
│ ├── next_name_test.dart
│ ├── selection_set_test.dart
│ ├── type_test.dart
│ ├── value_test.dart
│ ├── variable_definition_test.dart
│ └── variable_test.dart
├── graphql_schema
├── .gitignore
├── CHANGELOG.md
├── LICENSE
├── README.md
├── analysis_options.yaml
├── example
│ └── example.dart
├── graphql_schema.iml
├── lib
│ ├── graphql_schema.dart
│ └── src
│ │ ├── argument.dart
│ │ ├── enum.dart
│ │ ├── field.dart
│ │ ├── gen.dart
│ │ ├── object_type.dart
│ │ ├── scalar.dart
│ │ ├── schema.dart
│ │ ├── type.dart
│ │ ├── union.dart
│ │ └── validation_result.dart
├── mono_pkg.yaml
├── pubspec.yaml
└── test
│ ├── common.dart
│ ├── equality_test.dart
│ ├── inheritance_test.dart
│ ├── serialize_test.dart
│ └── validation_test.dart
├── graphql_server
├── .gitignore
├── CHANGELOG.md
├── LICENSE
├── README.md
├── analysis_options.yaml
├── example
│ └── main.dart
├── graphql_server.iml
├── lib
│ ├── graphql_server.dart
│ ├── introspection.dart
│ ├── mirrors.dart
│ ├── src
│ │ └── apollo
│ │ │ ├── remote_client.dart
│ │ │ ├── server.dart
│ │ │ └── transport.dart
│ └── subscriptions_transport_ws.dart
├── mono_pkg.yaml
├── pubspec.yaml
└── test
│ ├── common.dart
│ ├── mirrors_test.dart
│ ├── query_test.dart
│ └── subscription_test.dart
├── img
├── angel_graphql.png
├── angel_logo.png
└── angel_logo.xcf
├── travis.sh
└── video.png
/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by .ignore support plugin (hsz.mobi)
2 | ### JetBrains template
3 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
4 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
5 |
6 | # User-specific stuff
7 | .idea/**/workspace.xml
8 | .idea/**/tasks.xml
9 | .idea/**/dictionaries
10 | .idea/**/shelf
11 |
12 | # Sensitive or high-churn files
13 | .idea/**/dataSources/
14 | .idea/**/dataSources.ids
15 | .idea/**/dataSources.local.xml
16 | .idea/**/sqlDataSources.xml
17 | .idea/**/dynamic.xml
18 | .idea/**/uiDesigner.xml
19 | .idea/**/dbnavigator.xml
20 |
21 | # Gradle
22 | .idea/**/gradle.xml
23 | .idea/**/libraries
24 |
25 | # CMake
26 | cmake-build-debug/
27 | cmake-build-release/
28 |
29 | # Mongo Explorer plugin
30 | .idea/**/mongoSettings.xml
31 |
32 | # File-based project format
33 | *.iws
34 |
35 | # IntelliJ
36 | out/
37 |
38 | # mpeltonen/sbt-idea plugin
39 | .idea_modules/
40 |
41 | # JIRA plugin
42 | atlassian-ide-plugin.xml
43 |
44 | # Cursive Clojure plugin
45 | .idea/replstate.xml
46 |
47 | # Crashlytics plugin (for Android Studio and IntelliJ)
48 | com_crashlytics_export_strings.xml
49 | crashlytics.properties
50 | crashlytics-build.properties
51 | fabric.properties
52 |
53 | # Editor-based Rest Client
54 | .idea/httpRequests
55 |
56 | .dart_tool
--------------------------------------------------------------------------------
/.idea/graphql_parser.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/runConfigurations/main_dart.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/runConfigurations/objects_in_equality_test_dart.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/runConfigurations/server_dart.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/runConfigurations/tests_in_comment_test_dart.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/runConfigurations/tests_in_graphql_parser.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/runConfigurations/tests_in_graphql_schema.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/runConfigurations/tests_in_mirrors_test_dart.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/runConfigurations/tests_in_query_test_dart.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/runConfigurations/tests_in_validation_test_dart.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/runConfigurations/tests_in_value_test_dart.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: dart
2 | dart:
3 | - dev
4 | - stable
5 | script:
6 | - bash -ex travis.sh
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 The Angel Framework
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 |
4 |
5 |

6 |

7 |
8 |
9 |
10 | A complete implementation of the official
11 | [GraphQL specification](https://graphql.github.io/graphql-spec/June2018/),
12 | in the Dart programming language.
13 |
14 | The goal of this project is to provide to server-side
15 | users of Dart an alternative to REST API's.
16 |
17 | Included is also
18 | `package:angel_graphql`, which, when combined with the
19 | [Angel](https://github.com/angel-dart) framework, allows
20 | server-side Dart users to build backends with GraphQL and
21 | virtually any database imaginable.
22 |
23 | ## Tutorial Demo (click to watch)
24 | [](https://youtu.be/5x6S4kDODa8)
25 |
26 | ## Projects
27 | This mono repo is split into several sub-projects,
28 | each with its own detailed documentation and examples:
29 | * `angel_graphql` - Support for handling GraphQL via HTTP and
30 | WebSockets in the [Angel](https://angel-dart.dev) framework. Also serves as the `package:graphql_server` reference implementation.
31 | * `data_loader` - A Dart port of [`graphql/data_loader`](https://github.com/graphql/dataloader).
32 | * `example_star_wars`: An example GraphQL API built using
33 | `package:angel_graphql`.
34 | * `graphql_generator`: Generates `package:graphql_schema` object types from concrete Dart classes.
35 | * `graphql_parser`: A recursive descent parser for the GraphQL language.
36 | * `graphql_schema`: An implementation of GraphQL's type system. This, combined with `package:graphql_parser`,
37 | powers `package:graphql_server`.
38 | * `graphql_server`: Base functionality for implementing GraphQL servers in Dart. Has no dependency on any
39 | framework.
--------------------------------------------------------------------------------
/angel_graphql/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://www.dartlang.org/tools/private-files.html
2 |
3 | # Files and directories created by pub
4 | .buildlog
5 | .packages
6 | .project
7 | .pub/
8 | .scripts-bin/
9 | build/
10 | **/packages/
11 | posts.json
12 |
13 | # Files created by dart2js
14 | # (Most Dart developers will use pub build to compile Dart, use/modify these
15 | # rules if you intend to use dart2js directly
16 | # Convention is to use extension '.dart.js' for Dart compiled to Javascript to
17 | # differentiate from explicit Javascript files)
18 | *.dart.js
19 | *.part.js
20 | *.js.deps
21 | *.js.map
22 | *.info.json
23 |
24 | # Directory created by dartdoc
25 | doc/api/
26 |
27 | # Don't commit pubspec lock file
28 | # (Library packages only! Remove pattern if developing an application package)
29 | pubspec.lock
30 | ### Dart template
31 | # See https://www.dartlang.org/tools/private-files.html
32 |
33 | # Files and directories created by pub
34 |
35 | # SDK 1.20 and later (no longer creates packages directories)
36 |
37 | # Older SDK versions
38 | # (Include if the minimum SDK version specified in pubsepc.yaml is earlier than 1.20)
39 |
40 |
41 | # Files created by dart2js
42 | # (Most Dart developers will use pub build to compile Dart, use/modify these
43 | # rules if you intend to use dart2js directly
44 | # Convention is to use extension '.dart.js' for Dart compiled to Javascript to
45 | # differentiate from explicit Javascript files)
46 |
47 | # Directory created by dartdoc
48 |
49 | # Don't commit pubspec lock file
50 | # (Library packages only! Remove pattern if developing an application package)
51 | ### JetBrains template
52 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
53 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
54 |
55 | # User-specific stuff:
56 | ../.idea/workspace.xml
57 | .idea/**/tasks.xml
58 | .idea/dictionaries
59 |
60 | # Sensitive or high-churn files:
61 | .idea/**/dataSources/
62 | .idea/**/dataSources.ids
63 | .idea/**/dataSources.xml
64 | .idea/**/dataSources.local.xml
65 | .idea/**/sqlDataSources.xml
66 | .idea/**/dynamic.xml
67 | .idea/**/uiDesigner.xml
68 |
69 | # Gradle:
70 | .idea/**/gradle.xml
71 | .idea/**/libraries
72 |
73 | # Mongo Explorer plugin:
74 | .idea/**/mongoSettings.xml
75 |
76 | ## File-based project format:
77 | *.iws
78 |
79 | ## Plugin-specific files:
80 |
81 | # IntelliJ
82 | /out/
83 |
84 | # mpeltonen/sbt-idea plugin
85 | .idea_modules/
86 |
87 | # JIRA plugin
88 | atlassian-ide-plugin.xml
89 |
90 | # Crashlytics plugin (for Android Studio and IntelliJ)
91 | com_crashlytics_export_strings.xml
92 | crashlytics.properties
93 | crashlytics-build.properties
94 | fabric.properties
95 |
--------------------------------------------------------------------------------
/angel_graphql/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # 1.1.0
2 | * Support the GraphQL multipart spec: https://github.com/jaydenseric/graphql-multipart-request-spec
3 |
4 | # 1.0.0
5 | * Apply `package:pedantic`.
6 |
7 | # 1.0.0-rc.0
8 | * Finish `graphQLWS`.
9 |
10 | # 1.0.0-beta.1
11 | * Add `graphQLWS` handler, and support subscriptions.
12 |
13 | # 1.0.0-beta
14 | * Angel RC updates.
15 |
16 | # 1.0.0-alpha
17 | * First official release.
--------------------------------------------------------------------------------
/angel_graphql/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 The Angel Framework
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/angel_graphql/analysis_options.yaml:
--------------------------------------------------------------------------------
1 | include: package:pedantic/analysis_options.yaml
2 | analyzer:
3 | strong-mode:
4 | implicit-casts: false
--------------------------------------------------------------------------------
/angel_graphql/angel_graphql.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/angel_graphql/example/main.dart:
--------------------------------------------------------------------------------
1 | // ignore_for_file: deprecated_member_use
2 | import 'package:angel_framework/angel_framework.dart';
3 | import 'package:angel_framework/http.dart';
4 | import 'package:angel_graphql/angel_graphql.dart';
5 | import 'package:angel_serialize/angel_serialize.dart';
6 | import 'package:graphql_schema/graphql_schema.dart';
7 | import 'package:graphql_server/graphql_server.dart';
8 | import 'package:graphql_server/mirrors.dart';
9 | import 'package:logging/logging.dart';
10 |
11 | main() async {
12 | var logger = Logger('angel_graphql');
13 | var app = Angel(
14 | logger: logger
15 | ..onRecord.listen((rec) {
16 | print(rec);
17 | if (rec.error != null) print(rec.error);
18 | if (rec.stackTrace != null) print(rec.stackTrace);
19 | }));
20 | var http = AngelHttp(app);
21 |
22 | var todoService = app.use('api/todos', MapService());
23 |
24 | var queryType = objectType(
25 | 'Query',
26 | description: 'A simple API that manages your to-do list.',
27 | fields: [
28 | field(
29 | 'todos',
30 | listOf(convertDartType(Todo).nonNullable()),
31 | resolve: resolveViaServiceIndex(todoService),
32 | ),
33 | field(
34 | 'todo',
35 | convertDartType(Todo),
36 | resolve: resolveViaServiceRead(todoService),
37 | inputs: [
38 | GraphQLFieldInput('id', graphQLId.nonNullable()),
39 | ],
40 | ),
41 | ],
42 | );
43 |
44 | var mutationType = objectType(
45 | 'Mutation',
46 | description: 'Modify the to-do list.',
47 | fields: [
48 | field(
49 | 'createTodo',
50 | convertDartType(Todo),
51 | inputs: [
52 | GraphQLFieldInput(
53 | 'data', convertDartType(Todo).coerceToInputObject()),
54 | ],
55 | resolve: resolveViaServiceCreate(todoService),
56 | ),
57 | ],
58 | );
59 |
60 | var schema = graphQLSchema(
61 | queryType: queryType,
62 | mutationType: mutationType,
63 | );
64 |
65 | app.all('/graphql', graphQLHttp(GraphQL(schema)));
66 | app.get('/graphiql', graphiQL());
67 |
68 | await todoService
69 | .create({'text': 'Clean your room!', 'completion_status': 'COMPLETE'});
70 | await todoService.create(
71 | {'text': 'Take out the trash', 'completion_status': 'INCOMPLETE'});
72 | await todoService.create({
73 | 'text': 'Become a billionaire at the age of 5',
74 | 'completion_status': 'INCOMPLETE'
75 | });
76 |
77 | var server = await http.startServer('127.0.0.1', 3000);
78 | var uri =
79 | Uri(scheme: 'http', host: server.address.address, port: server.port);
80 | var graphiqlUri = uri.replace(path: 'graphiql');
81 | print('Listening at $uri');
82 | print('Access graphiql at $graphiqlUri');
83 | }
84 |
85 | @GraphQLDocumentation(description: 'Any object with a .text (String) property.')
86 | abstract class HasText {
87 | String get text;
88 | }
89 |
90 | @serializable
91 | @GraphQLDocumentation(
92 | description: 'A task that might not be completed yet. **Yay! Markdown!**')
93 | class Todo extends Model implements HasText {
94 | String text;
95 |
96 | @GraphQLDocumentation(deprecationReason: 'Use `completion_status` instead.')
97 | bool completed;
98 |
99 | CompletionStatus completionStatus;
100 |
101 | Todo({this.text, this.completed, this.completionStatus});
102 | }
103 |
104 | @GraphQLDocumentation(description: 'The completion status of a to-do item.')
105 | enum CompletionStatus { COMPLETE, INCOMPLETE }
106 |
--------------------------------------------------------------------------------
/angel_graphql/example/subscription.dart:
--------------------------------------------------------------------------------
1 | // Inspired by:
2 | // https://www.apollographql.com/docs/apollo-server/features/subscriptions/#subscriptions-example
3 |
4 | import 'package:angel_file_service/angel_file_service.dart';
5 | import 'package:angel_framework/angel_framework.dart';
6 | import 'package:angel_framework/http.dart';
7 | import 'package:angel_graphql/angel_graphql.dart';
8 | import 'package:file/local.dart';
9 | import 'package:graphql_schema/graphql_schema.dart';
10 | import 'package:graphql_server/graphql_server.dart';
11 | import 'package:logging/logging.dart';
12 |
13 | main() async {
14 | var logger = Logger('angel_graphql');
15 | var app = Angel(logger: logger);
16 | var http = AngelHttp(app);
17 | app.logger.onRecord.listen((rec) {
18 | print(rec);
19 | if (rec.error != null) print(rec.error);
20 | if (rec.stackTrace != null) print(rec.stackTrace);
21 | });
22 |
23 | // Create an in-memory service.
24 | var fs = LocalFileSystem();
25 | var postService =
26 | app.use('/api/posts', JsonFileService(fs.file('posts.json')));
27 |
28 | // Also get a [Stream] of item creation events.
29 | var postAdded = postService.afterCreated
30 | .asStream()
31 | .map((e) => {'postAdded': e.result})
32 | .asBroadcastStream();
33 |
34 | // GraphQL setup.
35 | var postType = objectType('Post', fields: [
36 | field('author', graphQLString),
37 | field('comment', graphQLString),
38 | ]);
39 |
40 | var schema = graphQLSchema(
41 | // Hooked up to the postService:
42 | // type Query { posts: [Post] }
43 | queryType: objectType(
44 | 'Query',
45 | fields: [
46 | field(
47 | 'posts',
48 | listOf(postType),
49 | resolve: resolveViaServiceIndex(postService),
50 | ),
51 | ],
52 | ),
53 |
54 | // Hooked up to the postService:
55 | // type Mutation {
56 | // addPost(author: String!, comment: String!): Post
57 | // }
58 | mutationType: objectType(
59 | 'Mutation',
60 | fields: [
61 | field(
62 | 'addPost',
63 | postType,
64 | inputs: [
65 | GraphQLFieldInput(
66 | 'data', postType.toInputObject('PostInput').nonNullable()),
67 | ],
68 | resolve: resolveViaServiceCreate(postService),
69 | ),
70 | ],
71 | ),
72 |
73 | // Hooked up to `postAdded`:
74 | // type Subscription { postAdded: Post }
75 | subscriptionType: objectType(
76 | 'Subscription',
77 | fields: [
78 | field('postAdded', postType, resolve: (_, __) => postAdded),
79 | ],
80 | ),
81 | );
82 |
83 | // Mount GraphQL routes; we'll support HTTP and WebSockets transports.
84 | app.all('/graphql', graphQLHttp(GraphQL(schema)));
85 | app.get('/subscriptions',
86 | graphQLWS(GraphQL(schema), keepAliveInterval: Duration(seconds: 3)));
87 | app.get('/graphiql',
88 | graphiQL(subscriptionsEndpoint: 'ws://localhost:3000/subscriptions'));
89 |
90 | var server = await http.startServer('127.0.0.1', 3000);
91 | var uri =
92 | Uri(scheme: 'http', host: server.address.address, port: server.port);
93 | var graphiqlUri = uri.replace(path: 'graphiql');
94 | var postsUri = uri.replace(pathSegments: ['api', 'posts']);
95 | print('Listening at $uri');
96 | print('Access graphiql at $graphiqlUri');
97 | print('Access posts service at $postsUri');
98 | }
99 |
--------------------------------------------------------------------------------
/angel_graphql/lib/angel_graphql.dart:
--------------------------------------------------------------------------------
1 | import 'package:angel_framework/angel_framework.dart';
2 | import 'package:graphql_schema/graphql_schema.dart';
3 | export 'src/graphiql.dart';
4 | export 'src/graphql_http.dart';
5 | export 'src/graphql_ws.dart';
6 | export 'src/resolvers.dart';
7 |
8 | /// The canonical [GraphQLUploadType] instance.
9 | final GraphQLUploadType graphQLUpload = GraphQLUploadType();
10 |
11 | /// A [GraphQLScalarType] that is used to read uploaded files from
12 | /// `multipart/form-data` requests.
13 | class GraphQLUploadType extends GraphQLScalarType {
14 | @override
15 | String get name => 'Upload';
16 |
17 | @override
18 | String get description =>
19 | 'Represents a file that has been uploaded to the server.';
20 |
21 | @override
22 | GraphQLType coerceToInputObject() => this;
23 |
24 | @override
25 | UploadedFile deserialize(UploadedFile serialized) => serialized;
26 |
27 | @override
28 | UploadedFile serialize(UploadedFile value) => value;
29 |
30 | @override
31 | ValidationResult validate(String key, UploadedFile input) {
32 | if (input != null && input is! UploadedFile) {
33 | return _Vr(false, errors: ['Expected "$key" to be a boolean.']);
34 | }
35 | return _Vr(true, value: input);
36 | }
37 | }
38 |
39 | // TODO: Really need to make the validation result constructors *public*
40 | class _Vr implements ValidationResult {
41 | final bool successful;
42 | final List errors;
43 | final T value;
44 |
45 | _Vr(this.successful, {this.errors, this.value});
46 | }
47 |
--------------------------------------------------------------------------------
/angel_graphql/lib/src/graphiql.dart:
--------------------------------------------------------------------------------
1 | import 'package:angel_framework/angel_framework.dart';
2 | import 'package:http_parser/http_parser.dart';
3 |
4 | /// Returns a simple [RequestHandler] that renders the GraphiQL visual interface for GraphQL.
5 | ///
6 | /// By default, the interface expects your backend to be mounted at `/graphql`; this is configurable
7 | /// via [graphQLEndpoint].
8 | RequestHandler graphiQL(
9 | {String graphQLEndpoint = '/graphql', String subscriptionsEndpoint}) {
10 | return (req, res) {
11 | res
12 | ..contentType = MediaType('text', 'html')
13 | ..write(renderGraphiql(
14 | graphqlEndpoint: graphQLEndpoint,
15 | subscriptionsEndpoint: subscriptionsEndpoint))
16 | ..close();
17 | };
18 | }
19 |
20 | String renderGraphiql(
21 | {String graphqlEndpoint = '/graphql', String subscriptionsEndpoint}) {
22 | var subscriptionsScripts = '',
23 | subscriptionsFetcher = '',
24 | fetcherName = 'graphQLFetcher';
25 |
26 | if (subscriptionsEndpoint != null) {
27 | fetcherName = 'subscriptionsFetcher';
28 | subscriptionsScripts = '''
29 |
30 |
31 | ''';
32 | subscriptionsFetcher = '''
33 | let subscriptionsClient = window.SubscriptionsTransportWs.SubscriptionClient('$subscriptionsEndpoint', {
34 | reconnect: true
35 | });
36 | let $fetcherName = window.GraphiQLSubscriptionsFetcher.graphQLFetcher(subscriptionsClient, graphQLFetcher);
37 | ''';
38 | }
39 |
40 | return '''
41 |
42 |
43 |
44 |
45 | Angel GraphQL
46 |
47 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 | $subscriptionsScripts
64 |
85 |
86 |
87 | '''
88 | .trim();
89 | }
90 |
--------------------------------------------------------------------------------
/angel_graphql/lib/src/graphql_ws.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 | import 'dart:io';
3 | import 'package:angel_framework/angel_framework.dart';
4 | import 'package:angel_framework/http.dart';
5 | import 'package:graphql_schema/graphql_schema.dart';
6 | import 'package:graphql_server/graphql_server.dart';
7 | import 'package:graphql_server/subscriptions_transport_ws.dart' as stw;
8 | import 'package:web_socket_channel/io.dart';
9 |
10 | /// A [RequestHandler] that serves a spec-compliant GraphQL backend, over WebSockets.
11 | /// This endpoint only supports WebSockets, and can be used to deliver subscription events.
12 | ///
13 | /// `graphQLWS` uses the Apollo WebSocket protocol, for the sake of compatibility with
14 | /// existing tooling.
15 | ///
16 | /// See:
17 | /// * https://github.com/apollographql/subscriptions-transport-ws
18 | RequestHandler graphQLWS(GraphQL graphQL, {Duration keepAliveInterval}) {
19 | return (req, res) async {
20 | if (req is HttpRequestContext) {
21 | if (WebSocketTransformer.isUpgradeRequest(req.rawRequest)) {
22 | await res.detach();
23 | var socket = await WebSocketTransformer.upgrade(req.rawRequest,
24 | protocolSelector: (protocols) {
25 | if (protocols.contains('graphql-ws')) {
26 | return 'graphql-ws';
27 | } else {
28 | throw AngelHttpException.badRequest(
29 | message: 'Only the "graphql-ws" protocol is allowed.');
30 | }
31 | });
32 | var channel = IOWebSocketChannel(socket);
33 | var client = stw.RemoteClient(channel.cast());
34 | var server =
35 | _GraphQLWSServer(client, graphQL, req, res, keepAliveInterval);
36 | await server.done;
37 | } else {
38 | throw AngelHttpException.badRequest(
39 | message: 'The `graphQLWS` endpoint only accepts WebSockets.');
40 | }
41 | } else {
42 | throw AngelHttpException.badRequest(
43 | message: 'The `graphQLWS` endpoint only accepts HTTP/1.1 requests.');
44 | }
45 | };
46 | }
47 |
48 | class _GraphQLWSServer extends stw.Server {
49 | final GraphQL graphQL;
50 | final RequestContext req;
51 | final ResponseContext res;
52 |
53 | _GraphQLWSServer(stw.RemoteClient client, this.graphQL, this.req, this.res,
54 | Duration keepAliveInterval)
55 | : super(client, keepAliveInterval: keepAliveInterval);
56 |
57 | @override
58 | bool onConnect(stw.RemoteClient client, [Map connectionParams]) => true;
59 |
60 | @override
61 | Future onOperation(String id, String query,
62 | [Map variables, String operationName]) async {
63 | try {
64 | var globalVariables = {
65 | '__requestctx': req,
66 | '__responsectx': res,
67 | };
68 | var data = await graphQL.parseAndExecute(
69 | query,
70 | operationName: operationName,
71 | sourceUrl: 'input',
72 | globalVariables: globalVariables,
73 | variableValues: variables,
74 | );
75 | return stw.GraphQLResult(data);
76 | } on GraphQLException catch (e) {
77 | return stw.GraphQLResult(null, errors: e.errors);
78 | }
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/angel_graphql/mono_pkg.yaml:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angel-dart-archive/graphql/33e2f86ba73d559197b6270df036256104726aca/angel_graphql/mono_pkg.yaml
--------------------------------------------------------------------------------
/angel_graphql/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: angel_graphql
2 | version: 1.1.0
3 | description: The fastest + easiest way to get a GraphQL backend in Dart, using Angel.
4 | homepage: https://github.com/angel-dart/graphql
5 | author: Tobe O
6 | environment:
7 | sdk: ">=2.0.0-dev <3.0.0"
8 | dependencies:
9 | angel_file_service: ^2.0.0
10 | angel_framework: ^2.0.0
11 | angel_websocket: ^2.0.0
12 | angel_validate: ^2.0.0
13 | graphql_parser: ^1.0.0
14 | graphql_schema: ^1.0.0
15 | graphql_server: ^1.0.0
16 | http_parser: ^3.0.0
17 | web_socket_channel: ^1.0.0
18 | dev_dependencies:
19 | angel_serialize: ^2.0.0
20 | file: ^5.0.0
21 | logging: ^0.11.0
22 | pedantic: ^1.0.0
--------------------------------------------------------------------------------
/data_loader/.gitignore:
--------------------------------------------------------------------------------
1 | .packages
2 | pubspec.lock
3 | .dart_tool
4 | doc/api
--------------------------------------------------------------------------------
/data_loader/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # 1.0.0
2 | * Initial version.
--------------------------------------------------------------------------------
/data_loader/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 The Angel Framework
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/data_loader/README.md:
--------------------------------------------------------------------------------
1 | # data_loader
2 | [](https://pub.dartlang.org/packages/data_loader)
3 | [](https://travis-ci.org/angel-dart/graphql)
4 |
5 |
6 | Batch and cache database lookups. Works well with GraphQL.
7 | Ported from the original JS version:
8 | https://github.com/graphql/dataloader
9 |
10 | ## Installation
11 | In your pubspec.yaml:
12 |
13 | ```yaml
14 | dependencies:
15 | data_loader: ^1.0.0
16 | ```
17 |
18 | ## Usage
19 | Complete example:
20 | https://github.com/angel-dart/graphql/blob/master/data_loader/example/main.dart
21 |
22 | ```dart
23 | var userLoader = new DataLoader((key) => myBatchGetUsers(keys));
24 | var invitedBy = await userLoader.load(1)then(user => userLoader.load(user.invitedByID))
25 | print('User 1 was invited by $invitedBy'));
26 | ```
--------------------------------------------------------------------------------
/data_loader/analysis_options.yaml:
--------------------------------------------------------------------------------
1 | include: package:pedantic/analysis_options.yaml
2 | analyzer:
3 | strong-mode:
4 | implicit-casts: false
--------------------------------------------------------------------------------
/data_loader/example/main.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 | import 'package:data_loader/data_loader.dart';
3 | import 'package:graphql_schema/graphql_schema.dart';
4 |
5 | external Future> fetchTodos(Iterable ids);
6 |
7 | main() async {
8 | // Create a DataLoader. By default, it caches lookups.
9 | var todoLoader = DataLoader(fetchTodos); // DataLoader
10 |
11 | // type Todo { id: Int, text: String, is_complete: Boolean }
12 | var todoType = objectType(
13 | 'Todo',
14 | fields: [
15 | field('id', graphQLInt),
16 | field('text', graphQLString),
17 | field('is_complete', graphQLBoolean),
18 | ],
19 | );
20 |
21 | // type Query { todo($id: Int!) Todo }
22 | // ignore: unused_local_variable
23 | var schema = graphQLSchema(
24 | queryType: objectType(
25 | 'Query',
26 | fields: [
27 | field(
28 | 'todo',
29 | listOf(todoType),
30 | inputs: [GraphQLFieldInput('id', graphQLInt.nonNullable())],
31 | resolve: (_, args) => todoLoader.load(args['id'] as int),
32 | ),
33 | ],
34 | ),
35 | );
36 |
37 | // Do something with your schema...
38 | }
39 |
40 | abstract class Todo {
41 | int get id;
42 | String get text;
43 | bool get isComplete;
44 | }
45 |
--------------------------------------------------------------------------------
/data_loader/lib/data_loader.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 | import 'dart:collection';
3 |
4 | /// A utility for batching multiple requests together, to improve application performance.
5 | ///
6 | /// Enqueues batches of requests until the next tick, when they are processed in bulk.
7 | ///
8 | /// Port of Facebook's `DataLoader`:
9 | /// https://github.com/graphql/dataloader
10 | class DataLoader {
11 | /// Invoked to fetch a batch of keys simultaneously.
12 | final FutureOr> Function(Iterable) loadMany;
13 |
14 | /// Whether to use a memoization cache to store the results of past lookups.
15 | final bool cache;
16 |
17 | var _cache = {};
18 | var _queue = Queue<_QueueItem>();
19 | bool _started = false;
20 |
21 | DataLoader(this.loadMany, {this.cache = true});
22 |
23 | Future _onTick() async {
24 | if (_queue.isNotEmpty) {
25 | var current = _queue.toList();
26 | _queue.clear();
27 |
28 | List loadIds =
29 | current.map((i) => i.id).toSet().toList(growable: false);
30 |
31 | var data = await loadMany(
32 | loadIds,
33 | );
34 |
35 | for (int i = 0; i < loadIds.length; i++) {
36 | var id = loadIds[i];
37 | var value = data.elementAt(i);
38 |
39 | if (cache) _cache[id] = value;
40 |
41 | current
42 | .where((item) => item.id == id)
43 | .forEach((item) => item.completer.complete(value));
44 | }
45 | }
46 |
47 | _started = false;
48 | // if (!_closed) scheduleMicrotask(_onTick);
49 | }
50 |
51 | /// Clears the value at [key], if it exists.
52 | void clear(Id key) => _cache.remove(key);
53 |
54 | /// Clears the entire cache.
55 | void clearAll() => _cache.clear();
56 |
57 | /// Primes the cache with the provided key and value. If the key already exists, no change is made.
58 | ///
59 | /// To forcefully prime the cache, clear the key first with
60 | /// `loader..clear(key)..prime(key, value)`.
61 | void prime(Id key, Data value) => _cache.putIfAbsent(key, () => value);
62 |
63 | /// Closes this [DataLoader], cancelling all pending requests.
64 | void close() {
65 | while (_queue.isNotEmpty) {
66 | _queue.removeFirst().completer.completeError(
67 | StateError('The DataLoader was closed before the item was loaded.'));
68 | }
69 |
70 | _queue.clear();
71 | }
72 |
73 | /// Returns a [Future] that completes when the next batch of requests completes.
74 | Future load(Id id) {
75 | if (cache && _cache.containsKey(id)) {
76 | return Future.value(_cache[id]);
77 | } else {
78 | var item = _QueueItem(id);
79 | _queue.add(item);
80 | if (!_started) {
81 | _started = true;
82 | scheduleMicrotask(_onTick);
83 | }
84 | return item.completer.future;
85 | }
86 | }
87 | }
88 |
89 | class _QueueItem {
90 | final Id id;
91 | final Completer completer = Completer();
92 |
93 | _QueueItem(this.id);
94 | }
95 |
--------------------------------------------------------------------------------
/data_loader/mono_pkg.yaml:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angel-dart-archive/graphql/33e2f86ba73d559197b6270df036256104726aca/data_loader/mono_pkg.yaml
--------------------------------------------------------------------------------
/data_loader/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: data_loader
2 | version: 1.0.0
3 | author: Tobe O
4 | description: Batch and cache database lookups. Works well with GraphQL. Ported from JS.
5 | homepage: https://github.com/angel-dart/graphql
6 | environment:
7 | sdk: ">=2.0.0-dev <3.0.0"
8 | dev_dependencies:
9 | graphql_schema: ^1.0.0
10 | pedantic: ^1.0.0
11 | test: ">=0.12.0 <2.0.0"
--------------------------------------------------------------------------------
/data_loader/test/all_test.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 |
3 | import 'package:data_loader/data_loader.dart';
4 | import 'package:test/test.dart';
5 |
6 | void main() {
7 | var numbers = List.generate(10, (i) => i.toStringAsFixed(2));
8 | var numberLoader = DataLoader((ids) {
9 | print('ID batch: $ids');
10 | return ids.map((i) => numbers[i]);
11 | });
12 |
13 | test('batch', () async {
14 | var zero = numberLoader.load(0);
15 | var one = numberLoader.load(1);
16 | var two = numberLoader.load(2);
17 | var batch = await Future.wait([zero, one, two]);
18 | print('Fetched result: $batch');
19 | expect(batch, ['0.00', '1.00', '2.00']);
20 | });
21 |
22 | test('dedupe', () async {
23 | var loader = DataLoader>>((ids) {
24 | return ids.map(
25 | (i) => {i: ids.toList()},
26 | );
27 | });
28 |
29 | var zero = loader.load(0);
30 | var one = loader.load(1);
31 | var two = loader.load(2);
32 | var anotherZero = loader.load(0);
33 | var batch = await Future.wait([zero, one, two, anotherZero]);
34 |
35 | expect(
36 | batch,
37 | [
38 | { 0: [0, 1, 2]},
39 | { 1: [0, 1, 2]},
40 | { 2: [0, 1, 2]},
41 | { 0: [0, 1, 2]},
42 | ],
43 | );
44 | });
45 |
46 | group('cache', () {
47 | DataLoader uniqueLoader, noCache;
48 |
49 | setUp(() {
50 | uniqueLoader = DataLoader((ids) async {
51 | var numbers = await numberLoader.loadMany(ids);
52 | return numbers.map((s) => _Unique(s));
53 | });
54 | noCache = DataLoader(uniqueLoader.loadMany, cache: false);
55 | });
56 |
57 | tearDown(() {
58 | uniqueLoader.close();
59 | noCache.close();
60 | });
61 |
62 | test('only lookup once', () async {
63 | var a = await uniqueLoader.load(3);
64 | var b = await uniqueLoader.load(3);
65 | expect(a, b);
66 | });
67 |
68 | test('can be disabled', () async {
69 | var a = await noCache.load(3);
70 | var b = await noCache.load(3);
71 | expect(a, isNot(b));
72 | });
73 |
74 | test('clear', () async {
75 | var a = await uniqueLoader.load(3);
76 | uniqueLoader.clear(3);
77 | var b = await uniqueLoader.load(3);
78 | expect(a, isNot(b));
79 | });
80 |
81 | test('clearAll', () async {
82 | var a = await uniqueLoader.load(3);
83 | uniqueLoader.clearAll();
84 | var b = await uniqueLoader.load(3);
85 | expect(a, isNot(b));
86 | });
87 |
88 | test('prime', () async {
89 | uniqueLoader.prime(3, _Unique('hey'));
90 | var a = await uniqueLoader.load(3);
91 | expect(a.value, 'hey');
92 | });
93 | });
94 | }
95 |
96 | class _Unique {
97 | final String value;
98 |
99 | _Unique(this.value);
100 | }
101 |
--------------------------------------------------------------------------------
/example_star_wars/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://www.dartlang.org/tools/private-files.html
2 |
3 | # Files and directories created by pub
4 | .buildlog
5 | .packages
6 | .project
7 | .pub/
8 | .scripts-bin/
9 | build/
10 | **/packages/
11 |
12 | # Files created by dart2js
13 | # (Most Dart developers will use pub build to compile Dart, use/modify these
14 | # rules if you intend to use dart2js directly
15 | # Convention is to use extension '.dart.js' for Dart compiled to Javascript to
16 | # differentiate from explicit Javascript files)
17 | *.dart.js
18 | *.part.js
19 | *.js.deps
20 | *.js.map
21 | *.info.json
22 |
23 | # Directory created by dartdoc
24 | doc/api/
25 |
26 | # Don't commit pubspec lock file
27 | # (Library packages only! Remove pattern if developing an application package)
28 | pubspec.lock
29 | ### Dart template
30 | # See https://www.dartlang.org/tools/private-files.html
31 |
32 | # Files and directories created by pub
33 |
34 | # SDK 1.20 and later (no longer creates packages directories)
35 |
36 | # Older SDK versions
37 | # (Include if the minimum SDK version specified in pubsepc.yaml is earlier than 1.20)
38 |
39 |
40 | # Files created by dart2js
41 | # (Most Dart developers will use pub build to compile Dart, use/modify these
42 | # rules if you intend to use dart2js directly
43 | # Convention is to use extension '.dart.js' for Dart compiled to Javascript to
44 | # differentiate from explicit Javascript files)
45 |
46 | # Directory created by dartdoc
47 |
48 | # Don't commit pubspec lock file
49 | # (Library packages only! Remove pattern if developing an application package)
50 | ### JetBrains template
51 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
52 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
53 |
54 | # User-specific stuff:
55 | ../.idea/workspace.xml
56 | .idea/**/tasks.xml
57 | .idea/dictionaries
58 |
59 | # Sensitive or high-churn files:
60 | .idea/**/dataSources/
61 | .idea/**/dataSources.ids
62 | .idea/**/dataSources.xml
63 | .idea/**/dataSources.local.xml
64 | .idea/**/sqlDataSources.xml
65 | .idea/**/dynamic.xml
66 | .idea/**/uiDesigner.xml
67 |
68 | # Gradle:
69 | .idea/**/gradle.xml
70 | .idea/**/libraries
71 |
72 | # Mongo Explorer plugin:
73 | .idea/**/mongoSettings.xml
74 |
75 | ## File-based project format:
76 | *.iws
77 |
78 | ## Plugin-specific files:
79 |
80 | # IntelliJ
81 | /out/
82 |
83 | # mpeltonen/sbt-idea plugin
84 | .idea_modules/
85 |
86 | # JIRA plugin
87 | atlassian-ide-plugin.xml
88 |
89 | # Crashlytics plugin (for Android Studio and IntelliJ)
90 | com_crashlytics_export_strings.xml
91 | crashlytics.properties
92 | crashlytics-build.properties
93 | fabric.properties
94 |
--------------------------------------------------------------------------------
/example_star_wars/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 The Angel Framework
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/example_star_wars/analysis_options.yaml:
--------------------------------------------------------------------------------
1 | analyzer:
2 | strong-mode:
3 | implicit-casts: false
--------------------------------------------------------------------------------
/example_star_wars/bin/server.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 | import 'dart:io';
3 |
4 | import 'package:angel_framework/angel_framework.dart';
5 | import 'package:angel_hot/angel_hot.dart';
6 | import 'package:logging/logging.dart';
7 | import 'package:star_wars/src/pretty_logging.dart' as star_wars;
8 | import 'package:star_wars/star_wars.dart' as star_wars;
9 |
10 | main() async {
11 | Future createServer() async {
12 | hierarchicalLoggingEnabled = true;
13 | var logger = Logger.detached('star_wars')
14 | ..onRecord.listen(star_wars.prettyLog);
15 | var app = Angel(logger: logger);
16 | await app.configure(star_wars.configureServer);
17 | return app;
18 | }
19 |
20 | var hot = HotReloader(createServer, [Directory('lib')]);
21 |
22 | var server = await hot.startServer('127.0.0.1', 3000);
23 | var serverUrl =
24 | Uri(scheme: 'http', host: server.address.address, port: server.port);
25 | var graphiQLUrl = serverUrl.replace(path: '/graphiql');
26 | print('Listening at $serverUrl');
27 | print('GraphiQL endpoint: $graphiQLUrl');
28 | }
29 |
--------------------------------------------------------------------------------
/example_star_wars/example_star_wars.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/example_star_wars/lib/src/models/character.dart:
--------------------------------------------------------------------------------
1 | import 'package:graphql_schema/graphql_schema.dart';
2 | import 'episode.dart';
3 | part 'character.g.dart';
4 |
5 | @graphQLClass
6 | abstract class Character {
7 | String get id;
8 |
9 | String get name;
10 |
11 | // List get appearsIn;
12 | }
13 |
--------------------------------------------------------------------------------
/example_star_wars/lib/src/models/character.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'character.dart';
4 |
5 | // **************************************************************************
6 | // _GraphQLGenerator
7 | // **************************************************************************
8 |
9 | /// Auto-generated from [Character].
10 | final GraphQLObjectType characterGraphQLType = objectType('Character',
11 | isInterface: true,
12 | interfaces: [],
13 | fields: [field('id', graphQLString), field('name', graphQLString)]);
14 |
--------------------------------------------------------------------------------
/example_star_wars/lib/src/models/droid.dart:
--------------------------------------------------------------------------------
1 | import 'package:angel_model/angel_model.dart';
2 | import 'package:angel_serialize/angel_serialize.dart';
3 | import 'package:collection/collection.dart';
4 | import 'package:graphql_schema/graphql_schema.dart';
5 | import 'character.dart';
6 | import 'episode.dart';
7 | part 'droid.g.dart';
8 |
9 | @serializable
10 | @graphQLClass
11 | @GraphQLDocumentation(description: 'Beep! Boop!')
12 | abstract class _Droid extends Model implements Character {
13 | String get id;
14 |
15 | String get name;
16 |
17 | @GraphQLDocumentation(
18 | description: 'The list of episodes this droid appears in.')
19 | List get appearsIn;
20 |
21 | /// Doc comments automatically become GraphQL descriptions.
22 | List get friends;
23 | }
24 |
--------------------------------------------------------------------------------
/example_star_wars/lib/src/models/episode.dart:
--------------------------------------------------------------------------------
1 | import 'package:graphql_schema/graphql_schema.dart';
2 | part 'episode.g.dart';
3 |
4 | @GraphQLDocumentation(
5 | description: 'The episodes of the Star Wars original trilogy.')
6 | @graphQLClass
7 | enum Episode {
8 | NEWHOPE,
9 | EMPIRE,
10 | JEDI,
11 | }
12 |
--------------------------------------------------------------------------------
/example_star_wars/lib/src/models/episode.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'episode.dart';
4 |
5 | // **************************************************************************
6 | // _GraphQLGenerator
7 | // **************************************************************************
8 |
9 | /// Auto-generated from [Episode].
10 | final GraphQLEnumType episodeGraphQLType = enumTypeFromStrings(
11 | 'Episode', const ['NEWHOPE', 'EMPIRE', 'JEDI'],
12 | description: 'The episodes of the Star Wars original trilogy.');
13 |
--------------------------------------------------------------------------------
/example_star_wars/lib/src/models/human.dart:
--------------------------------------------------------------------------------
1 | import 'package:angel_model/angel_model.dart';
2 | import 'package:angel_serialize/angel_serialize.dart';
3 | import 'package:collection/collection.dart';
4 | import 'package:graphql_schema/graphql_schema.dart';
5 | import 'character.dart';
6 | import 'episode.dart';
7 | part 'human.g.dart';
8 |
9 | @serializable
10 | @graphQLClass
11 | abstract class _Human extends Model implements Character {
12 | // @GraphQLDocumentation(description: "This human's name, of course.")
13 | // String name;
14 | // List friends;
15 | // List appearsIn;
16 | // List starships;
17 | // int totalCredits;
18 |
19 | String get id;
20 |
21 | String get name;
22 |
23 | List get appearsIn;
24 |
25 | List get friends;
26 |
27 | int get totalCredits;
28 |
29 | // Human(
30 | // {this.name,
31 | // this.friends,
32 | // this.appearsIn,
33 | // this.starships,
34 | // this.totalCredits});
35 | }
36 |
--------------------------------------------------------------------------------
/example_star_wars/lib/src/models/models.dart:
--------------------------------------------------------------------------------
1 | export 'character.dart';
2 | export 'droid.dart';
3 | export 'episode.dart';
4 | export 'human.dart';
5 | export 'starship.dart';
6 |
--------------------------------------------------------------------------------
/example_star_wars/lib/src/models/starship.dart:
--------------------------------------------------------------------------------
1 | import 'package:angel_model/angel_model.dart';
2 | import 'package:angel_serialize/angel_serialize.dart';
3 | import 'package:graphql_schema/graphql_schema.dart';
4 | part 'starship.g.dart';
5 |
6 | @serializable
7 | @graphQLClass
8 | abstract class _Starship extends Model {
9 | String get name;
10 | int get length;
11 | }
12 |
--------------------------------------------------------------------------------
/example_star_wars/lib/src/models/starship.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'starship.dart';
4 |
5 | // **************************************************************************
6 | // JsonModelGenerator
7 | // **************************************************************************
8 |
9 | @generatedSerializable
10 | class Starship extends _Starship {
11 | Starship({this.id, this.name, this.length, this.createdAt, this.updatedAt});
12 |
13 | @override
14 | final String id;
15 |
16 | @override
17 | final String name;
18 |
19 | @override
20 | final int length;
21 |
22 | @override
23 | final DateTime createdAt;
24 |
25 | @override
26 | final DateTime updatedAt;
27 |
28 | Starship copyWith(
29 | {String id,
30 | String name,
31 | int length,
32 | DateTime createdAt,
33 | DateTime updatedAt}) {
34 | return new Starship(
35 | id: id ?? this.id,
36 | name: name ?? this.name,
37 | length: length ?? this.length,
38 | createdAt: createdAt ?? this.createdAt,
39 | updatedAt: updatedAt ?? this.updatedAt);
40 | }
41 |
42 | bool operator ==(other) {
43 | return other is _Starship &&
44 | other.id == id &&
45 | other.name == name &&
46 | other.length == length &&
47 | other.createdAt == createdAt &&
48 | other.updatedAt == updatedAt;
49 | }
50 |
51 | @override
52 | int get hashCode {
53 | return hashObjects([id, name, length, createdAt, updatedAt]);
54 | }
55 |
56 | Map toJson() {
57 | return StarshipSerializer.toMap(this);
58 | }
59 | }
60 |
61 | // **************************************************************************
62 | // SerializerGenerator
63 | // **************************************************************************
64 |
65 | abstract class StarshipSerializer {
66 | static Starship fromMap(Map map) {
67 | return new Starship(
68 | id: map['id'] as String,
69 | name: map['name'] as String,
70 | length: map['length'] as int,
71 | createdAt: map['created_at'] != null
72 | ? (map['created_at'] is DateTime
73 | ? (map['created_at'] as DateTime)
74 | : DateTime.parse(map['created_at'].toString()))
75 | : null,
76 | updatedAt: map['updated_at'] != null
77 | ? (map['updated_at'] is DateTime
78 | ? (map['updated_at'] as DateTime)
79 | : DateTime.parse(map['updated_at'].toString()))
80 | : null);
81 | }
82 |
83 | static Map toMap(_Starship model) {
84 | if (model == null) {
85 | return null;
86 | }
87 | return {
88 | 'id': model.id,
89 | 'name': model.name,
90 | 'length': model.length,
91 | 'created_at': model.createdAt?.toIso8601String(),
92 | 'updated_at': model.updatedAt?.toIso8601String()
93 | };
94 | }
95 | }
96 |
97 | abstract class StarshipFields {
98 | static const List allFields = [
99 | id,
100 | name,
101 | length,
102 | createdAt,
103 | updatedAt
104 | ];
105 |
106 | static const String id = 'id';
107 |
108 | static const String name = 'name';
109 |
110 | static const String length = 'length';
111 |
112 | static const String createdAt = 'created_at';
113 |
114 | static const String updatedAt = 'updated_at';
115 | }
116 |
117 | // **************************************************************************
118 | // _GraphQLGenerator
119 | // **************************************************************************
120 |
121 | /// Auto-generated from [Starship].
122 | final GraphQLObjectType starshipGraphQLType =
123 | objectType('Starship', isInterface: false, interfaces: [], fields: [
124 | field('id', graphQLString),
125 | field('name', graphQLString),
126 | field('length', graphQLInt),
127 | field('created_at', graphQLDate),
128 | field('updated_at', graphQLDate),
129 | field('idAsInt', graphQLInt)
130 | ]);
131 |
--------------------------------------------------------------------------------
/example_star_wars/lib/src/pretty_logging.dart:
--------------------------------------------------------------------------------
1 | import 'package:angel_http_exception/angel_http_exception.dart';
2 | import 'package:logging/logging.dart';
3 | import 'package:io/ansi.dart';
4 |
5 | /// Prints the contents of a [LogRecord] with pretty colors.
6 | void prettyLog(LogRecord record) {
7 | var code = chooseLogColor(record.level);
8 |
9 | if (record.error == null) print(code.wrap(record.toString()));
10 |
11 | if (record.error != null) {
12 | var err = record.error;
13 | if (err is AngelHttpException && err.statusCode != 500) return;
14 | print(code.wrap(record.toString() + '\n'));
15 | print(code.wrap(err.toString()));
16 |
17 | if (record.stackTrace != null) {
18 | print(code.wrap(record.stackTrace.toString()));
19 | }
20 | }
21 | }
22 |
23 | /// Chooses a color based on the logger [level].
24 | AnsiCode chooseLogColor(Level level) {
25 | if (level == Level.SHOUT)
26 | return backgroundRed;
27 | else if (level == Level.SEVERE)
28 | return red;
29 | else if (level == Level.WARNING)
30 | return yellow;
31 | else if (level == Level.INFO)
32 | return cyan;
33 | else if (level == Level.FINER || level == Level.FINEST) return lightGray;
34 | return resetAll;
35 | }
36 |
--------------------------------------------------------------------------------
/example_star_wars/mono_pkg.yaml:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angel-dart-archive/graphql/33e2f86ba73d559197b6270df036256104726aca/example_star_wars/mono_pkg.yaml
--------------------------------------------------------------------------------
/example_star_wars/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: star_wars
2 | publish_to: none
3 | dependencies:
4 | #angel_file_service: ^1.0.0
5 | angel_graphql:
6 | path: ../angel_graphql
7 | angel_hot: ^2.0.0-alpha
8 | angel_serialize: ^2.0.0
9 | io: ^0.3.2
10 | dev_dependencies:
11 | angel_serialize_generator: ^2.0.0
12 | build_runner: ^1.0.0
13 | graphql_generator:
14 | path: ../graphql_generator
15 | dependency_overrides:
16 | graphql_parser:
17 | path: ../graphql_parser
18 | graphql_schema:
19 | path: ../graphql_schema
20 | graphql_server:
21 | path: ../graphql_server
--------------------------------------------------------------------------------
/graphql.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/graphql_generator/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://www.dartlang.org/tools/private-files.html
2 |
3 | # Files and directories created by pub
4 | .buildlog
5 | .packages
6 | .project
7 | .pub/
8 | .scripts-bin/
9 | build/
10 | **/packages/
11 |
12 | # Files created by dart2js
13 | # (Most Dart developers will use pub build to compile Dart, use/modify these
14 | # rules if you intend to use dart2js directly
15 | # Convention is to use extension '.dart.js' for Dart compiled to Javascript to
16 | # differentiate from explicit Javascript files)
17 | *.dart.js
18 | *.part.js
19 | *.js.deps
20 | *.js.map
21 | *.info.json
22 |
23 | # Directory created by dartdoc
24 | doc/api/
25 |
26 | # Don't commit pubspec lock file
27 | # (Library packages only! Remove pattern if developing an application package)
28 | pubspec.lock
29 | ### Dart template
30 | # See https://www.dartlang.org/tools/private-files.html
31 |
32 | # Files and directories created by pub
33 |
34 | # SDK 1.20 and later (no longer creates packages directories)
35 |
36 | # Older SDK versions
37 | # (Include if the minimum SDK version specified in pubsepc.yaml is earlier than 1.20)
38 |
39 |
40 | # Files created by dart2js
41 | # (Most Dart developers will use pub build to compile Dart, use/modify these
42 | # rules if you intend to use dart2js directly
43 | # Convention is to use extension '.dart.js' for Dart compiled to Javascript to
44 | # differentiate from explicit Javascript files)
45 |
46 | # Directory created by dartdoc
47 |
48 | # Don't commit pubspec lock file
49 | # (Library packages only! Remove pattern if developing an application package)
50 | ### JetBrains template
51 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
52 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
53 |
54 | # User-specific stuff:
55 | ../.idea/workspace.xml
56 | .idea/**/tasks.xml
57 | .idea/dictionaries
58 |
59 | # Sensitive or high-churn files:
60 | .idea/**/dataSources/
61 | .idea/**/dataSources.ids
62 | .idea/**/dataSources.xml
63 | .idea/**/dataSources.local.xml
64 | .idea/**/sqlDataSources.xml
65 | .idea/**/dynamic.xml
66 | .idea/**/uiDesigner.xml
67 |
68 | # Gradle:
69 | .idea/**/gradle.xml
70 | .idea/**/libraries
71 |
72 | # Mongo Explorer plugin:
73 | .idea/**/mongoSettings.xml
74 |
75 | ## File-based project format:
76 | *.iws
77 |
78 | ## Plugin-specific files:
79 |
80 | # IntelliJ
81 | /out/
82 |
83 | # mpeltonen/sbt-idea plugin
84 | .idea_modules/
85 |
86 | # JIRA plugin
87 | atlassian-ide-plugin.xml
88 |
89 | # Crashlytics plugin (for Android Studio and IntelliJ)
90 | com_crashlytics_export_strings.xml
91 | crashlytics.properties
92 | crashlytics-build.properties
93 | fabric.properties
94 |
--------------------------------------------------------------------------------
/graphql_generator/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # 1.0.0+1
2 | * Replace `snakeCase` with `camelCase`.
3 |
4 | # 1.0.0
5 | * Apply `package:pedantic`.
6 |
7 | # 1.0.0-rc.1
8 | * Add `CHANGELOG.md`, `example/main.dart`.
9 | * Add documentation to `README.md`.
--------------------------------------------------------------------------------
/graphql_generator/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 The Angel Framework
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/graphql_generator/README.md:
--------------------------------------------------------------------------------
1 | # graphql_generator
2 | [](https://pub.dartlang.org/packages/graphql_generator)
3 | [](https://travis-ci.org/angel-dart/graphql)
4 |
5 | Generates `package:graphql_schema` schemas for
6 | annotated class.
7 |
8 | Replaces `convertDartType` from `package:graphql_server`.
9 |
10 | ## Usage
11 | Usage is very simple. You just need a `@graphQLClass` or `@GraphQLClass()` annotation
12 | on any class you want to generate an object type for.
13 |
14 | Individual fields can have a `@GraphQLDocumentation()` annotation, to provide information
15 | like descriptions, deprecation reasons, etc.
16 |
17 | ```dart
18 | @graphQLClass
19 | class Todo {
20 | String text;
21 |
22 | @GraphQLDocumentation(description: 'Whether this item is complete.')
23 | bool isComplete;
24 | }
25 |
26 | void main() {
27 | print(todoGraphQLType.fields.map((f) => f.name));
28 | }
29 | ```
30 |
31 | The following is generated (as of April 18th, 2019):
32 |
33 | ```dart
34 | // GENERATED CODE - DO NOT MODIFY BY HAND
35 |
36 | part of 'main.dart';
37 |
38 | // **************************************************************************
39 | // _GraphQLGenerator
40 | // **************************************************************************
41 |
42 | /// Auto-generated from [Todo].
43 | final GraphQLObjectType todoGraphQLType = objectType('Todo',
44 | isInterface: false,
45 | interfaces: [],
46 | fields: [
47 | field('text', graphQLString),
48 | field('isComplete', graphQLBoolean)
49 | ]);
50 | ```
--------------------------------------------------------------------------------
/graphql_generator/analysis_options.yaml:
--------------------------------------------------------------------------------
1 | include: package:pedantic/analysis_options.yaml
2 | analyzer:
3 | strong-mode:
4 | implicit-casts: false
--------------------------------------------------------------------------------
/graphql_generator/build.yaml:
--------------------------------------------------------------------------------
1 | builders:
2 | graphql:
3 | import: "package:graphql_generator/graphql_generator.dart"
4 | builder_factories:
5 | - graphQLBuilder
6 | auto_apply: root_package
7 | build_to: cache
8 | build_extensions:
9 | .dart:
10 | - graphql_generator.g.part
11 | required_inputs:
12 | - angel_serialize.g.part
13 | applies_builders:
14 | - source_gen|combining_builder
--------------------------------------------------------------------------------
/graphql_generator/example/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:graphql_schema/graphql_schema.dart';
2 | part 'main.g.dart';
3 |
4 | @graphQLClass
5 | class TodoItem {
6 | String text;
7 |
8 | @GraphQLDocumentation(description: 'Whether this item is complete.')
9 | bool isComplete;
10 | }
11 |
12 | void main() {
13 | print(todoItemGraphQLType.fields.map((f) => f.name));
14 | }
15 |
--------------------------------------------------------------------------------
/graphql_generator/example/main.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'main.dart';
4 |
5 | // **************************************************************************
6 | // _GraphQLGenerator
7 | // **************************************************************************
8 |
9 | /// Auto-generated from [TodoItem].
10 | final GraphQLObjectType todoItemGraphQLType = objectType('TodoItem',
11 | isInterface: false,
12 | interfaces: [],
13 | fields: [
14 | field('text', graphQLString),
15 | field('isComplete', graphQLBoolean)
16 | ]);
17 |
--------------------------------------------------------------------------------
/graphql_generator/mono_pkg.yaml:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angel-dart-archive/graphql/33e2f86ba73d559197b6270df036256104726aca/graphql_generator/mono_pkg.yaml
--------------------------------------------------------------------------------
/graphql_generator/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: graphql_generator
2 | version: 1.0.0+1
3 | description: Generates GraphQL schemas from Dart classes, for use with pkg:graphql_server.
4 | author: Tobe O
5 | homepage: https://github.com/angel-dart/graphql
6 | environment:
7 | sdk: ">=2.0.0 <3.0.0"
8 | dependencies:
9 | analyzer: ">=0.27.1 <2.0.0"
10 | angel_model: ^1.0.0
11 | angel_serialize_generator: ^2.0.0
12 | build: ^1.0.0
13 | build_config: ^0.3.0
14 | code_builder: ^3.0.0
15 | graphql_schema: ^1.0.2
16 | recase: ^2.0.0
17 | source_gen: ^0.9.4
18 | dev_dependencies:
19 | build_runner: ^1.0.0
20 | pedantic: ^1.0.0
--------------------------------------------------------------------------------
/graphql_parser/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://www.dartlang.org/tools/private-files.html
2 |
3 | # Files and directories created by pub
4 | .buildlog
5 | .packages
6 | .project
7 | .pub/
8 | .scripts-bin/
9 | build/
10 | **/packages/
11 |
12 | # Files created by dart2js
13 | # (Most Dart developers will use pub build to compile Dart, use/modify these
14 | # rules if you intend to use dart2js directly
15 | # Convention is to use extension '.dart.js' for Dart compiled to Javascript to
16 | # differentiate from explicit Javascript files)
17 | *.dart.js
18 | *.part.js
19 | *.js.deps
20 | *.js.map
21 | *.info.json
22 |
23 | # Directory created by dartdoc
24 | doc/api/
25 |
26 | # Don't commit pubspec lock file
27 | # (Library packages only! Remove pattern if developing an application package)
28 | pubspec.lock
29 | ### Dart template
30 | # See https://www.dartlang.org/tools/private-files.html
31 |
32 | # Files and directories created by pub
33 |
34 | # SDK 1.20 and later (no longer creates packages directories)
35 |
36 | # Older SDK versions
37 | # (Include if the minimum SDK version specified in pubsepc.yaml is earlier than 1.20)
38 |
39 |
40 | # Files created by dart2js
41 | # (Most Dart developers will use pub build to compile Dart, use/modify these
42 | # rules if you intend to use dart2js directly
43 | # Convention is to use extension '.dart.js' for Dart compiled to Javascript to
44 | # differentiate from explicit Javascript files)
45 |
46 | # Directory created by dartdoc
47 |
48 | # Don't commit pubspec lock file
49 | # (Library packages only! Remove pattern if developing an application package)
50 | ### JetBrains template
51 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
52 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
53 |
54 | # User-specific stuff:
55 | ../.idea/workspace.xml
56 | .idea/**/tasks.xml
57 | .idea/dictionaries
58 |
59 | # Sensitive or high-churn files:
60 | .idea/**/dataSources/
61 | .idea/**/dataSources.ids
62 | .idea/**/dataSources.xml
63 | .idea/**/dataSources.local.xml
64 | .idea/**/sqlDataSources.xml
65 | .idea/**/dynamic.xml
66 | .idea/**/uiDesigner.xml
67 |
68 | # Gradle:
69 | .idea/**/gradle.xml
70 | .idea/**/libraries
71 |
72 | # Mongo Explorer plugin:
73 | .idea/**/mongoSettings.xml
74 |
75 | ## File-based project format:
76 | *.iws
77 |
78 | ## Plugin-specific files:
79 |
80 | # IntelliJ
81 | /out/
82 |
83 | # mpeltonen/sbt-idea plugin
84 | .idea_modules/
85 |
86 | # JIRA plugin
87 | atlassian-ide-plugin.xml
88 |
89 | # Crashlytics plugin (for Android Studio and IntelliJ)
90 | com_crashlytics_export_strings.xml
91 | crashlytics.properties
92 | crashlytics-build.properties
93 | fabric.properties
94 |
95 | .dart_tool
--------------------------------------------------------------------------------
/graphql_parser/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # 1.2.0
2 | * Combine `ValueContext` and `VariableContext` into a single `InputValueContext` supertype.
3 | * Add `T computeValue(Map variables);`
4 | * Resolve [#23](https://github.com/angel-dart/graphql/issues/23).
5 | * Deprecate old `ValueOrVariable` class, and parser/AST methods related to it.
6 |
7 | # 1.1.4
8 | * Fix broken int variable parsing - https://github.com/angel-dart/graphql/pull/32
9 |
10 | # 1.1.3
11 | * Add `Parser.nextName`, and remove all formerly-reserved words from the lexer.
12 | Resolves [#19](https://github.com/angel-dart/graphql/issues/19).
13 |
14 | # 1.1.2
15 | * Parse the `subscription` keyword.
16 |
17 | # 1.1.1
18 | * Pubspec updates for Dart 2.
19 |
20 | # 1.1.0
21 | * Removed `GraphQLVisitor`.
22 | * Enable parsing operations without an explicit
23 | name.
24 | * Parse `null`.
25 | * Completely ignore commas.
26 | * Ignore Unicode BOM, as per the spec.
27 | * Parse object values.
28 | * Parse enum values.
29 |
--------------------------------------------------------------------------------
/graphql_parser/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 The Angel Framework
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/graphql_parser/README.md:
--------------------------------------------------------------------------------
1 | # graphql_parser
2 | [](https://pub.dartlang.org/packages/graphql_parser)
3 | [](https://travis-ci.org/angel-dart/graphql)
4 |
5 | Parses GraphQL queries and schemas.
6 |
7 | *This library is merely a parser/visitor*. Any sort of actual GraphQL API functionality must be implemented by you,
8 | or by a third-party package.
9 |
10 | [Angel framework](https://angel-dart.github.io)
11 | users should consider
12 | [`package:angel_graphql`](https://pub.dartlang.org/packages/angel_graphql)
13 | as a dead-simple way to add GraphQL functionality to their servers.
14 |
15 | # Installation
16 | Add `graphql_parser` as a dependency in your `pubspec.yaml` file:
17 |
18 | ```yaml
19 | dependencies:
20 | graphql_parser: ^1.0.0
21 | ```
22 |
23 | # Usage
24 | The AST featured in this library was originally directly based off this ANTLR4 grammar created by Joseph T. McBride:
25 | https://github.com/antlr/grammars-v4/blob/master/graphql/GraphQL.g4
26 |
27 | It has since been updated to reflect upon the grammar in the official GraphQL
28 | specification (
29 | [June 2018](https://facebook.github.io/graphql/June2018/)).
30 |
31 | ```dart
32 | import 'package:graphql_parser/graphql_parser.dart';
33 |
34 | doSomething(String text) {
35 | var tokens = scan(text);
36 | var parser = Parser(tokens);
37 |
38 | if (parser.errors.isNotEmpty) {
39 | // Handle errors...
40 | }
41 |
42 | // Parse the GraphQL document using recursive descent
43 | var doc = parser.parseDocument();
44 |
45 | // Do something with the parsed GraphQL document...
46 | }
47 | ```
48 |
--------------------------------------------------------------------------------
/graphql_parser/analysis_options.yaml:
--------------------------------------------------------------------------------
1 | include: package:pedantic/analysis_options.yaml
2 | analyzer:
3 | strong-mode:
4 | implicit-casts: false
--------------------------------------------------------------------------------
/graphql_parser/example/example.dart:
--------------------------------------------------------------------------------
1 | import 'package:graphql_parser/graphql_parser.dart';
2 |
3 | final String text = '''
4 | {
5 | project(name: "GraphQL") {
6 | tagline
7 | }
8 | }
9 | '''
10 | .trim();
11 |
12 | main() {
13 | var tokens = scan(text);
14 | var parser = Parser(tokens);
15 | var doc = parser.parseDocument();
16 |
17 | var operation = doc.definitions.first as OperationDefinitionContext;
18 |
19 | var projectField = operation.selectionSet.selections.first.field;
20 | print(projectField.fieldName.name); // project
21 | print(projectField.arguments.first.name); // name
22 | print(projectField.arguments.first.value); // GraphQL
23 |
24 | var taglineField = projectField.selectionSet.selections.first.field;
25 | print(taglineField.fieldName.name); // tagline
26 | }
27 |
--------------------------------------------------------------------------------
/graphql_parser/graphql_parser.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/graphql_parser/lib/graphql_parser.dart:
--------------------------------------------------------------------------------
1 | export 'src/language/ast/ast.dart';
2 | export 'src/language/language.dart';
3 |
--------------------------------------------------------------------------------
/graphql_parser/lib/src/language/ast/alias.dart:
--------------------------------------------------------------------------------
1 | import 'package:source_span/source_span.dart';
2 | import '../token.dart';
3 | import 'node.dart';
4 |
5 | /// An alternate name for a field within a [SelectionSet].
6 | class AliasContext extends Node {
7 | /// The source tokens.
8 | final Token nameToken1, colonToken, nameToken2;
9 |
10 | AliasContext(this.nameToken1, this.colonToken, this.nameToken2);
11 |
12 | /// Use [nameToken1] instead.
13 | @deprecated
14 | Token get NAME1 => nameToken1;
15 |
16 | /// Use [colonToken] instead.
17 | @deprecated
18 | Token get COLON => colonToken;
19 |
20 | /// Use [nameToken2] instead.
21 | @deprecated
22 | Token get NAME2 => nameToken2;
23 |
24 | /// The aliased name of the value.
25 | String get alias => nameToken1.text;
26 |
27 | /// The actual name of the value.
28 | String get name => nameToken2.text;
29 |
30 | @override
31 | FileSpan get span =>
32 | nameToken1.span.expand(colonToken.span).expand(nameToken2.span);
33 | }
34 |
--------------------------------------------------------------------------------
/graphql_parser/lib/src/language/ast/argument.dart:
--------------------------------------------------------------------------------
1 | import 'package:source_span/source_span.dart';
2 | import '../token.dart';
3 | import 'node.dart';
4 | import 'input_value.dart';
5 |
6 | /// An argument passed to a [FieldContext].
7 | class ArgumentContext extends Node {
8 | /// The source tokens.
9 | final Token nameToken, colonToken;
10 |
11 | /// The value of the argument.
12 | final InputValueContext value;
13 |
14 | ArgumentContext(this.nameToken, this.colonToken, this.value);
15 |
16 | /// Use [value] instead.
17 | @deprecated
18 | InputValueContext get valueOrVariable => value;
19 |
20 | /// Use [nameToken] instead.
21 | @deprecated
22 | Token get NAME => nameToken;
23 |
24 | /// Use [colonToken] instead.
25 | @deprecated
26 | Token get COLON => colonToken;
27 |
28 | /// The name of the argument, as a [String].
29 | String get name => nameToken.text;
30 |
31 | @override
32 | FileSpan get span =>
33 | nameToken.span.expand(colonToken.span).expand(value.span);
34 | }
35 |
--------------------------------------------------------------------------------
/graphql_parser/lib/src/language/ast/array_value.dart:
--------------------------------------------------------------------------------
1 | import 'package:source_span/source_span.dart';
2 | import '../token.dart';
3 | import 'input_value.dart';
4 |
5 | /// A GraphQL list value literal.
6 | class ListValueContext extends InputValueContext {
7 | /// The source tokens.
8 | final Token lBracketToken, rBracketToken;
9 |
10 | /// The child values.
11 | final List values = [];
12 |
13 | ListValueContext(this.lBracketToken, this.rBracketToken);
14 |
15 | /// Use [lBracketToken] instead.
16 | @deprecated
17 | Token get LBRACKET => lBracketToken;
18 |
19 | /// Use [rBracketToken] instead.
20 | @deprecated
21 | Token get RBRACKET => rBracketToken;
22 |
23 | @override
24 | FileSpan get span {
25 | var out =
26 | values.fold(lBracketToken.span, (o, v) => o.expand(v.span));
27 | return out.expand(rBracketToken.span);
28 | }
29 |
30 | @override
31 | computeValue(Map variables) {
32 | return values.map((v) => v.computeValue(variables)).toList();
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/graphql_parser/lib/src/language/ast/ast.dart:
--------------------------------------------------------------------------------
1 | library graphql_parser.language.ast;
2 |
3 | export 'alias.dart';
4 | export 'array_value.dart';
5 | export 'argument.dart';
6 | export 'boolean_value.dart';
7 | export 'default_value.dart';
8 | export 'definition.dart';
9 | export 'deprecated_value.dart';
10 | export 'directive.dart';
11 | export 'document.dart';
12 | export 'field.dart';
13 | export 'field_name.dart';
14 | export 'fragment_definition.dart';
15 | export 'fragment_spread.dart';
16 | export 'inline_fragment.dart';
17 | export 'input_value.dart';
18 | export 'list_type.dart';
19 | export 'misc_value.dart';
20 | export 'node.dart';
21 | export 'number_value.dart';
22 | export 'operation_definition.dart';
23 | export 'selection.dart';
24 | export 'selection_set.dart';
25 | export 'string_value.dart';
26 | export 'type.dart';
27 | export 'type_condition.dart';
28 | export 'type_name.dart';
29 | export 'variable.dart';
30 | export 'variable_definition.dart';
31 | export 'variable_definitions.dart';
32 |
--------------------------------------------------------------------------------
/graphql_parser/lib/src/language/ast/boolean_value.dart:
--------------------------------------------------------------------------------
1 | import 'package:source_span/source_span.dart';
2 | import 'input_value.dart';
3 | import '../token.dart';
4 |
5 | /// A GraphQL boolean value literal.
6 | class BooleanValueContext extends InputValueContext {
7 | bool _valueCache;
8 |
9 | /// The source token.
10 | final Token booleanToken;
11 |
12 | BooleanValueContext(this.booleanToken) {
13 | assert(booleanToken?.text == 'true' || booleanToken?.text == 'false');
14 | }
15 |
16 | /// The [bool] value of this literal.
17 | bool get booleanValue => _valueCache ??= booleanToken.text == 'true';
18 |
19 | /// Use [booleanToken] instead.
20 | @deprecated
21 | Token get BOOLEAN => booleanToken;
22 |
23 | @override
24 | FileSpan get span => booleanToken.span;
25 |
26 | @override
27 | bool computeValue(Map variables) => booleanValue;
28 | }
29 |
--------------------------------------------------------------------------------
/graphql_parser/lib/src/language/ast/default_value.dart:
--------------------------------------------------------------------------------
1 | import 'package:source_span/source_span.dart';
2 | import '../token.dart';
3 | import 'input_value.dart';
4 | import 'node.dart';
5 |
6 | /// The default value to be passed to an [ArgumentContext].
7 | class DefaultValueContext extends Node {
8 | /// The source token.
9 | final Token equalsToken;
10 |
11 | /// The default value for the argument.
12 | final InputValueContext value;
13 |
14 | DefaultValueContext(this.equalsToken, this.value);
15 |
16 | /// Use [equalsToken] instead.
17 | @deprecated
18 | Token get EQUALS => equalsToken;
19 |
20 | @override
21 | FileSpan get span => equalsToken.span.expand(value.span);
22 | }
23 |
--------------------------------------------------------------------------------
/graphql_parser/lib/src/language/ast/definition.dart:
--------------------------------------------------------------------------------
1 | import 'node.dart';
2 |
3 | /// The base class for top-level GraphQL definitions.
4 | abstract class DefinitionContext extends Node {}
5 |
6 | /// An executable definition.
7 | abstract class ExecutableDefinitionContext extends DefinitionContext {}
8 |
9 | /// An ad-hoc type system declared in GraphQL.
10 | abstract class TypeSystemDefinitionContext extends DefinitionContext {}
11 |
12 | /// An extension to an existing ad-hoc type system.
13 | abstract class TypeSystemExtensionContext extends DefinitionContext {}
14 |
--------------------------------------------------------------------------------
/graphql_parser/lib/src/language/ast/deprecated_value.dart:
--------------------------------------------------------------------------------
1 | import 'input_value.dart';
2 |
3 | /// Use [ConstantContext] instead. This class remains solely for backwards compatibility.
4 | @deprecated
5 | abstract class ValueContext extends InputValueContext {
6 | /// Return a constant value.
7 | T get value;
8 |
9 | @override
10 | T computeValue(Map variables) => value;
11 | }
12 |
--------------------------------------------------------------------------------
/graphql_parser/lib/src/language/ast/directive.dart:
--------------------------------------------------------------------------------
1 | import 'package:source_span/source_span.dart';
2 | import '../token.dart';
3 | import 'argument.dart';
4 | import 'input_value.dart';
5 | import 'node.dart';
6 |
7 | /// A GraphQL directive, which may or may not have runtime semantics.
8 | class DirectiveContext extends Node {
9 | /// The source tokens.
10 | final Token arrobaToken, nameToken, colonToken, lParenToken, rParenToken;
11 |
12 | /// The argument being passed as the directive.
13 | final ArgumentContext argument;
14 |
15 | /// The (optional) value being passed with the directive.
16 | final InputValueContext value;
17 |
18 | DirectiveContext(this.arrobaToken, this.nameToken, this.colonToken,
19 | this.lParenToken, this.rParenToken, this.argument, this.value) {
20 | assert(nameToken != null);
21 | }
22 |
23 | /// Use [value] instead.
24 | @deprecated
25 | InputValueContext get valueOrVariable => value;
26 |
27 | /// Use [arrobaToken] instead.
28 | @deprecated
29 | Token get ARROBA => arrobaToken;
30 |
31 | /// Use [nameToken] instead.
32 | @deprecated
33 | Token get NAME => nameToken;
34 |
35 | /// Use [colonToken] instead.
36 | @deprecated
37 | Token get COLON => colonToken;
38 |
39 | /// Use [lParenToken] instead.
40 | @deprecated
41 | Token get LPAREN => lParenToken;
42 |
43 | /// Use [rParenToken] instead.
44 | @deprecated
45 | Token get RPAREN => rParenToken;
46 |
47 | @override
48 | FileSpan get span {
49 | var out = arrobaToken.span.expand(nameToken.span);
50 |
51 | if (colonToken != null) {
52 | out = out.expand(colonToken.span).expand(value.span);
53 | } else if (lParenToken != null) {
54 | out = out
55 | .expand(lParenToken.span)
56 | .expand(argument.span)
57 | .expand(rParenToken.span);
58 | }
59 |
60 | return out;
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/graphql_parser/lib/src/language/ast/document.dart:
--------------------------------------------------------------------------------
1 | import 'package:source_span/source_span.dart';
2 | import 'definition.dart';
3 | import 'node.dart';
4 |
5 | /// A GraphQL document.
6 | class DocumentContext extends Node {
7 | /// The top-level definitions in the document.
8 | final List definitions = [];
9 |
10 | @override
11 | FileSpan get span {
12 | if (definitions.isEmpty) return null;
13 | return definitions
14 | .map((d) => d.span)
15 | .reduce((a, b) => a.expand(b));
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/graphql_parser/lib/src/language/ast/field.dart:
--------------------------------------------------------------------------------
1 | import 'package:source_span/source_span.dart';
2 | import 'argument.dart';
3 | import 'directive.dart';
4 | import 'field_name.dart';
5 | import 'node.dart';
6 | import 'selection_set.dart';
7 |
8 | /// A field in a GraphQL [SelectionSet].
9 | class FieldContext extends Node {
10 | /// The name of this field.
11 | final FieldNameContext fieldName;
12 |
13 | /// Any arguments this field expects.
14 | final List arguments = [];
15 |
16 | /// Any directives affixed to this field.
17 | final List directives = [];
18 |
19 | /// The list of selections to resolve on an object.
20 | final SelectionSetContext selectionSet;
21 |
22 | FieldContext(this.fieldName, [this.selectionSet]);
23 |
24 | @override
25 | FileSpan get span {
26 | if (selectionSet != null) {
27 | return fieldName.span.expand(selectionSet.span);
28 | } else if (directives.isNotEmpty) {
29 | return directives.fold(
30 | fieldName.span, (out, d) => out.expand(d.span));
31 | }
32 | if (arguments.isNotEmpty) {
33 | return arguments.fold(
34 | fieldName.span, (out, a) => out.expand(a.span));
35 | } else {
36 | return fieldName.span;
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/graphql_parser/lib/src/language/ast/field_name.dart:
--------------------------------------------------------------------------------
1 | import 'package:source_span/source_span.dart';
2 | import '../token.dart';
3 | import 'alias.dart';
4 | import 'node.dart';
5 |
6 | /// The name of a GraphQL [FieldContext], which may or may not be [alias]ed.
7 | class FieldNameContext extends Node {
8 | /// The source token.
9 | final Token nameToken;
10 |
11 | /// An (optional) alias for the field.
12 | final AliasContext alias;
13 |
14 | FieldNameContext(this.nameToken, [this.alias]) {
15 | assert(nameToken != null || alias != null);
16 | }
17 |
18 | /// Use [nameToken] instead.
19 | @deprecated
20 | Token get NAME => nameToken;
21 |
22 | /// The [String] value of the [nameToken], if any.
23 | String get name => nameToken?.text;
24 |
25 | @override
26 | FileSpan get span => alias?.span ?? nameToken.span;
27 | }
28 |
--------------------------------------------------------------------------------
/graphql_parser/lib/src/language/ast/fragment_definition.dart:
--------------------------------------------------------------------------------
1 | import '../token.dart';
2 | import 'definition.dart';
3 | import 'directive.dart';
4 | import 'package:source_span/source_span.dart';
5 | import 'selection_set.dart';
6 | import 'type_condition.dart';
7 |
8 | /// A GraphQL query fragment definition.
9 | class FragmentDefinitionContext extends ExecutableDefinitionContext {
10 | /// The source tokens.
11 | final Token fragmentToken, nameToken, onToken;
12 |
13 | /// The type to which this fragment applies.
14 | final TypeConditionContext typeCondition;
15 |
16 | /// Any directives on the fragment.
17 | final List directives = [];
18 |
19 | /// The selections to apply when the [typeCondition] is met.
20 | final SelectionSetContext selectionSet;
21 |
22 | /// The [String] value of the [nameToken].
23 | String get name => nameToken.text;
24 |
25 | FragmentDefinitionContext(this.fragmentToken, this.nameToken, this.onToken,
26 | this.typeCondition, this.selectionSet);
27 |
28 | /// Use [fragmentToken] instead.
29 | @deprecated
30 | Token get FRAGMENT => fragmentToken;
31 |
32 | /// Use [nameToken] instead.
33 | @deprecated
34 | Token get NAME => nameToken;
35 |
36 | /// Use [onToken] instead.
37 | @deprecated
38 | Token get ON => onToken;
39 |
40 | @override
41 | FileSpan get span {
42 | var out = fragmentToken.span
43 | .expand(nameToken.span)
44 | .expand(onToken.span)
45 | .expand(typeCondition.span);
46 | out = directives.fold(out, (o, d) => o.expand(d.span));
47 | return out.expand(selectionSet.span);
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/graphql_parser/lib/src/language/ast/fragment_spread.dart:
--------------------------------------------------------------------------------
1 | import '../token.dart';
2 | import 'directive.dart';
3 | import 'node.dart';
4 | import 'package:source_span/source_span.dart';
5 |
6 | /// A GraphQL fragment spread.
7 | class FragmentSpreadContext extends Node {
8 | /// The source tokens.
9 | final Token ellipsisToken, nameToken;
10 |
11 | /// Any directives affixed to this fragment spread.
12 | final List directives = [];
13 |
14 | FragmentSpreadContext(this.ellipsisToken, this.nameToken);
15 |
16 | /// The [String] value of the [nameToken].
17 | String get name => nameToken.text;
18 |
19 | /// Use [ellipsisToken] instead.
20 | @deprecated
21 | Token get ELLIPSIS => ellipsisToken;
22 |
23 | /// Use [nameToken] instead.
24 | @deprecated
25 | Token get NAME => nameToken;
26 |
27 | @override
28 | FileSpan get span {
29 | var out = ellipsisToken.span.expand(nameToken.span);
30 | if (directives.isEmpty) return out;
31 | return directives.fold(out, (o, d) => o.expand(d.span));
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/graphql_parser/lib/src/language/ast/inline_fragment.dart:
--------------------------------------------------------------------------------
1 | import '../token.dart';
2 | import 'directive.dart';
3 | import 'node.dart';
4 | import 'package:source_span/source_span.dart';
5 | import 'selection_set.dart';
6 | import 'type_condition.dart';
7 |
8 | /// An inline fragment, which typically appears in a [SelectionSetContext].
9 | class InlineFragmentContext extends Node {
10 | /// The source tokens.
11 | final Token ellipsisToken, onToken;
12 |
13 | /// The type which this fragment matches.
14 | final TypeConditionContext typeCondition;
15 |
16 | /// Any directives affixed to this inline fragment.
17 | final List directives = [];
18 |
19 | /// The selections applied when the [typeCondition] is met.
20 | final SelectionSetContext selectionSet;
21 |
22 | InlineFragmentContext(
23 | this.ellipsisToken, this.onToken, this.typeCondition, this.selectionSet);
24 |
25 | /// Use [ellipsisToken] instead.
26 | @deprecated
27 | Token get ELLIPSIS => ellipsisToken;
28 |
29 | /// Use [onToken] instead.
30 | @deprecated
31 | Token get ON => onToken;
32 |
33 | @override
34 | FileSpan get span {
35 | var out =
36 | ellipsisToken.span.expand(onToken.span).expand(typeCondition.span);
37 | out = directives.fold(out, (o, d) => o.expand(d.span));
38 | return out.expand(selectionSet.span);
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/graphql_parser/lib/src/language/ast/input_value.dart:
--------------------------------------------------------------------------------
1 | import 'node.dart';
2 |
3 | /// Represents a value in GraphQL.
4 | abstract class InputValueContext extends Node {
5 | /// Computes the value, relative to some set of [variables].
6 | T computeValue(Map variables);
7 | }
8 |
--------------------------------------------------------------------------------
/graphql_parser/lib/src/language/ast/list_type.dart:
--------------------------------------------------------------------------------
1 | import '../token.dart';
2 | import 'node.dart';
3 | import 'package:source_span/source_span.dart';
4 | import 'type.dart';
5 |
6 | /// Represents a type that holds a list of another type.
7 | class ListTypeContext extends Node {
8 | /// The source tokens.
9 | final Token lBracketToken, rBracketToken;
10 |
11 | /// The inner type.
12 | final TypeContext innerType;
13 |
14 | ListTypeContext(this.lBracketToken, this.innerType, this.rBracketToken);
15 |
16 | /// Use [innerType] instead.
17 | @deprecated
18 | TypeContext get type => innerType;
19 |
20 | /// Use [lBracketToken] instead.
21 | @deprecated
22 | Token get LBRACKET => lBracketToken;
23 |
24 | /// Use [rBracketToken] instead.
25 | @deprecated
26 | Token get RBRACKET => rBracketToken;
27 |
28 | @override
29 | FileSpan get span =>
30 | lBracketToken.span.expand(innerType.span).expand(rBracketToken.span);
31 | }
32 |
--------------------------------------------------------------------------------
/graphql_parser/lib/src/language/ast/misc_value.dart:
--------------------------------------------------------------------------------
1 | import 'package:source_span/source_span.dart';
2 | import '../token.dart';
3 | import 'input_value.dart';
4 | import 'node.dart';
5 |
6 | /// A GraphQL `null` literal.
7 | class NullValueContext extends InputValueContext {
8 | /// The source token.
9 | final Token nullToken;
10 |
11 | NullValueContext(this.nullToken);
12 |
13 | /// Use [nullToken] instead.
14 | @deprecated
15 | Token get NULL => nullToken;
16 |
17 | @override
18 | FileSpan get span => nullToken.span;
19 |
20 | @override
21 | Null computeValue(Map variables) => null;
22 | }
23 |
24 | /// A GraphQL enumeration literal.
25 | class EnumValueContext extends InputValueContext {
26 | /// The source token.
27 | final Token nameToken;
28 |
29 | EnumValueContext(this.nameToken);
30 |
31 | /// Use [nameToken] instead.
32 | @deprecated
33 | Token get NAME => nameToken;
34 |
35 | @override
36 | FileSpan get span => nameToken.span;
37 |
38 | @override
39 | String computeValue(Map variables) => nameToken.span.text;
40 | }
41 |
42 | /// A GraphQL object literal.
43 | class ObjectValueContext extends InputValueContext