From 1b288876083deb9daa70610a4d3ddfa45e01ae0b Mon Sep 17 00:00:00 2001 From: thomashii Date: Sun, 13 Jun 2021 18:11:45 +0800 Subject: [PATCH] Moved CLI and graphQL --- packages/cli/.DS_Store | Bin 6148 -> 0 bytes packages/cli/.gitignore | 80 -- packages/cli/.idea/angel_cli.iml | 19 - packages/cli/.idea/modules.xml | 8 - .../.idea/runConfigurations/Controller.xml | 8 - .../cli/.idea/runConfigurations/Doctor.xml | 7 - packages/cli/.idea/runConfigurations/Init.xml | 8 - .../cli/.idea/runConfigurations/Show_Help.xml | 7 - .../cli/.idea/runConfigurations/Update.xml | 8 - .../cli/.idea/runConfigurations/Version.xml | 7 - packages/cli/.travis.yml | 1 - packages/cli/AUTHORS.md | 2 - packages/cli/CHANGELOG.md | 92 --- packages/cli/LICENSE | 21 - packages/cli/README.md | 27 +- packages/cli/TODO.md | 8 - packages/cli/analysis_options.yaml | 3 - packages/cli/bin/angel.dart | 55 -- packages/cli/example/main.dart | 3 - packages/cli/lib/angel_cli.dart | 3 - packages/cli/lib/src/commands/commands.dart | 9 - packages/cli/lib/src/commands/deploy.dart | 17 - .../cli/lib/src/commands/deploy/nginx.dart | 52 -- .../cli/lib/src/commands/deploy/systemd.dart | 86 -- packages/cli/lib/src/commands/doctor.dart | 34 - packages/cli/lib/src/commands/init.dart | 324 -------- packages/cli/lib/src/commands/install.dart | 247 ------ packages/cli/lib/src/commands/key.dart | 30 - packages/cli/lib/src/commands/make.dart | 25 - .../cli/lib/src/commands/make/controller.dart | 123 --- packages/cli/lib/src/commands/make/maker.dart | 82 -- .../cli/lib/src/commands/make/migration.dart | 133 ---- packages/cli/lib/src/commands/make/model.dart | 122 --- .../cli/lib/src/commands/make/plugin.dart | 69 -- .../cli/lib/src/commands/make/service.dart | 136 ---- packages/cli/lib/src/commands/make/test.dart | 110 --- packages/cli/lib/src/commands/pub.dart | 12 - packages/cli/lib/src/commands/rename.dart | 194 ----- .../commands/service_generators/custom.dart | 27 - .../service_generators/file_service.dart | 48 -- .../service_generators/generator.dart | 46 -- .../src/commands/service_generators/map.dart | 15 - .../commands/service_generators/mongo.dart | 43 - .../commands/service_generators/rethink.dart | 49 -- .../service_generators.dart | 15 - packages/cli/lib/src/random_string.dart | 15 - packages/cli/lib/src/util.dart | 77 -- packages/cli/pubspec.yaml | 27 - packages/cli/screenshots/screenshot.png | Bin 84903 -> 0 bytes packages/graphql/.gitignore | 56 -- packages/graphql/.idea/graphql_parser.iml | 14 - packages/graphql/.idea/modules.xml | 13 - .../.idea/runConfigurations/main_dart.xml | 7 - .../objects_in_equality_test_dart.xml | 9 - .../.idea/runConfigurations/server_dart.xml | 8 - .../tests_in_comment_test_dart.xml | 6 - .../tests_in_graphql_parser.xml | 8 - .../tests_in_graphql_schema.xml | 8 - .../tests_in_mirrors_test_dart.xml | 7 - .../tests_in_query_test_dart.xml | 7 - .../tests_in_validation_test_dart.xml | 7 - .../tests_in_value_test_dart.xml | 7 - packages/graphql/.idea/vcs.xml | 6 - packages/graphql/.travis.yml | 6 - packages/graphql/LICENSE | 21 - packages/graphql/README.md | 40 +- packages/graphql/angel_graphql/.gitignore | 94 --- packages/graphql/angel_graphql/CHANGELOG.md | 17 - packages/graphql/angel_graphql/LICENSE | 21 - packages/graphql/angel_graphql/README.md | 297 ------- .../angel_graphql/analysis_options.yaml | 4 - .../graphql/angel_graphql/angel_graphql.iml | 15 - .../graphql/angel_graphql/example/main.dart | 105 --- .../angel_graphql/example/subscription.dart | 98 --- .../angel_graphql/lib/angel_graphql.dart | 46 -- .../angel_graphql/lib/src/graphiql.dart | 89 --- .../angel_graphql/lib/src/graphql_http.dart | 182 ----- .../angel_graphql/lib/src/graphql_ws.dart | 80 -- .../angel_graphql/lib/src/resolvers.dart | 143 ---- packages/graphql/angel_graphql/mono_pkg.yaml | 0 packages/graphql/angel_graphql/pubspec.yaml | 32 - packages/graphql/data_loader/.gitignore | 4 - packages/graphql/data_loader/CHANGELOG.md | 2 - packages/graphql/data_loader/LICENSE | 21 - packages/graphql/data_loader/README.md | 26 - .../graphql/data_loader/analysis_options.yaml | 4 - .../graphql/data_loader/example/main.dart | 44 -- .../graphql/data_loader/lib/data_loader.dart | 94 --- packages/graphql/data_loader/mono_pkg.yaml | 0 packages/graphql/data_loader/pubspec.yaml | 12 - .../graphql/data_loader/test/all_test.dart | 100 --- packages/graphql/example_star_wars/.gitignore | 93 --- packages/graphql/example_star_wars/LICENSE | 21 - .../example_star_wars/analysis_options.yaml | 3 - .../graphql/example_star_wars/bin/server.dart | 28 - .../example_star_wars/example_star_wars.iml | 14 - .../lib/src/models/character.dart | 12 - .../lib/src/models/character.g.dart | 13 - .../lib/src/models/droid.dart | 23 - .../lib/src/models/droid.g.dart | 164 ---- .../lib/src/models/episode.dart | 11 - .../lib/src/models/episode.g.dart | 12 - .../lib/src/models/human.dart | 35 - .../lib/src/models/human.g.dart | 172 ---- .../lib/src/models/models.dart | 5 - .../lib/src/models/starship.dart | 11 - .../lib/src/models/starship.g.dart | 130 ---- .../lib/src/pretty_logging.dart | 35 - .../example_star_wars/lib/star_wars.dart | 154 ---- .../graphql/example_star_wars/mono_pkg.yaml | 0 .../graphql/example_star_wars/pubspec.yaml | 27 - packages/graphql/graphql.iml | 11 - packages/graphql/graphql_generator/.gitignore | 93 --- .../graphql/graphql_generator/CHANGELOG.md | 9 - packages/graphql/graphql_generator/LICENSE | 21 - packages/graphql/graphql_generator/README.md | 52 -- .../graphql_generator/analysis_options.yaml | 4 - packages/graphql/graphql_generator/build.yaml | 14 - .../graphql_generator/example/main.dart | 14 - .../graphql_generator/example/main.g.dart | 16 - .../lib/graphql_generator.dart | 233 ------ .../graphql/graphql_generator/mono_pkg.yaml | 0 .../graphql/graphql_generator/pubspec.yaml | 23 - packages/graphql/graphql_parser/.gitignore | 95 --- packages/graphql/graphql_parser/CHANGELOG.md | 28 - packages/graphql/graphql_parser/LICENSE | 21 - packages/graphql/graphql_parser/README.md | 47 -- .../graphql_parser/analysis_options.yaml | 4 - .../graphql_parser/example/example.dart | 26 - .../graphql/graphql_parser/graphql_parser.iml | 15 - .../graphql_parser/lib/graphql_parser.dart | 2 - .../lib/src/language/ast/alias.dart | 33 - .../lib/src/language/ast/argument.dart | 34 - .../lib/src/language/ast/array_value.dart | 34 - .../lib/src/language/ast/ast.dart | 31 - .../lib/src/language/ast/boolean_value.dart | 28 - .../lib/src/language/ast/default_value.dart | 22 - .../lib/src/language/ast/definition.dart | 13 - .../src/language/ast/deprecated_value.dart | 11 - .../lib/src/language/ast/directive.dart | 62 -- .../lib/src/language/ast/document.dart | 17 - .../lib/src/language/ast/field.dart | 39 - .../lib/src/language/ast/field_name.dart | 27 - .../src/language/ast/fragment_definition.dart | 49 -- .../lib/src/language/ast/fragment_spread.dart | 33 - .../lib/src/language/ast/inline_fragment.dart | 40 - .../lib/src/language/ast/input_value.dart | 7 - .../lib/src/language/ast/list_type.dart | 31 - .../lib/src/language/ast/misc_value.dart | 105 --- .../lib/src/language/ast/node.dart | 5 - .../lib/src/language/ast/number_value.dart | 35 - .../language/ast/operation_definition.dart | 59 -- .../lib/src/language/ast/selection.dart | 19 - .../lib/src/language/ast/selection_set.dart | 45 -- .../lib/src/language/ast/string_value.dart | 88 --- .../lib/src/language/ast/type.dart | 34 - .../lib/src/language/ast/type_condition.dart | 12 - .../lib/src/language/ast/type_name.dart | 21 - .../lib/src/language/ast/variable.dart | 28 - .../src/language/ast/variable_definition.dart | 31 - .../language/ast/variable_definitions.dart | 30 - .../lib/src/language/language.dart | 7 - .../lib/src/language/lexer.dart | 75 -- .../lib/src/language/parser.dart | 615 --------------- .../lib/src/language/syntax_error.dart | 12 - .../lib/src/language/token.dart | 19 - .../lib/src/language/token_type.dart | 30 - packages/graphql/graphql_parser/mono_pkg.yaml | 0 packages/graphql/graphql_parser/pubspec.yaml | 15 - .../graphql_parser/test/argument_test.dart | 87 --- .../graphql_parser/test/comment_test.dart | 16 - .../graphql/graphql_parser/test/common.dart | 3 - .../graphql_parser/test/directive_test.dart | 117 --- .../graphql_parser/test/document_test.dart | 119 --- .../graphql_parser/test/field_test.dart | 143 ---- .../test/fragment_spread_test.dart | 58 -- .../test/inline_fragment_test.dart | 76 -- .../graphql_parser/test/issue23_test.dart | 94 --- .../graphql_parser/test/next_name_test.dart | 24 - .../test/selection_set_test.dart | 96 --- .../graphql_parser/test/type_test.dart | 101 --- .../graphql_parser/test/value_test.dart | 93 --- .../test/variable_definition_test.dart | 88 --- .../graphql_parser/test/variable_test.dart | 43 - packages/graphql/graphql_schema/.gitignore | 93 --- packages/graphql/graphql_schema/CHANGELOG.md | 12 - packages/graphql/graphql_schema/LICENSE | 21 - packages/graphql/graphql_schema/README.md | 156 ---- .../graphql_schema/analysis_options.yaml | 3 - .../graphql_schema/example/example.dart | 41 - .../graphql/graphql_schema/graphql_schema.iml | 15 - .../graphql_schema/lib/graphql_schema.dart | 1 - .../graphql_schema/lib/src/argument.dart | 52 -- .../graphql/graphql_schema/lib/src/enum.dart | 104 --- .../graphql/graphql_schema/lib/src/field.dart | 62 -- .../graphql/graphql_schema/lib/src/gen.dart | 49 -- .../graphql_schema/lib/src/object_type.dart | 299 ------- .../graphql_schema/lib/src/scalar.dart | 158 ---- .../graphql_schema/lib/src/schema.dart | 159 ---- .../graphql/graphql_schema/lib/src/type.dart | 170 ---- .../graphql/graphql_schema/lib/src/union.dart | 88 --- .../lib/src/validation_result.dart | 28 - packages/graphql/graphql_schema/mono_pkg.yaml | 0 packages/graphql/graphql_schema/pubspec.yaml | 13 - .../graphql/graphql_schema/test/common.dart | 15 - .../graphql_schema/test/equality_test.dart | 113 --- .../graphql_schema/test/inheritance_test.dart | 67 -- .../graphql_schema/test/serialize_test.dart | 133 ---- .../graphql_schema/test/validation_test.dart | 102 --- packages/graphql/graphql_server/.gitignore | 93 --- packages/graphql/graphql_server/CHANGELOG.md | 40 - packages/graphql/graphql_server/LICENSE | 21 - packages/graphql/graphql_server/README.md | 127 --- .../graphql_server/analysis_options.yaml | 4 - .../graphql/graphql_server/example/main.dart | 52 -- .../graphql/graphql_server/graphql_server.iml | 15 - .../graphql_server/lib/graphql_server.dart | 734 ------------------ .../graphql_server/lib/introspection.dart | 528 ------------- .../graphql/graphql_server/lib/mirrors.dart | 367 --------- .../lib/src/apollo/remote_client.dart | 32 - .../graphql_server/lib/src/apollo/server.dart | 133 ---- .../lib/src/apollo/transport.dart | 78 -- .../lib/subscriptions_transport_ws.dart | 9 - packages/graphql/graphql_server/mono_pkg.yaml | 0 packages/graphql/graphql_server/pubspec.yaml | 25 - .../graphql/graphql_server/test/common.dart | 5 - .../graphql_server/test/mirrors_test.dart | 52 -- .../graphql_server/test/query_test.dart | 52 -- .../test/subscription_test.dart | 51 -- packages/graphql/img/angel_graphql.png | Bin 129666 -> 0 bytes packages/graphql/img/angel_logo.png | Bin 35179 -> 0 bytes packages/graphql/img/angel_logo.xcf | Bin 125938 -> 0 bytes packages/graphql/travis.sh | 6 - packages/graphql/video.png | Bin 234346 -> 0 bytes 234 files changed, 4 insertions(+), 13313 deletions(-) delete mode 100644 packages/cli/.DS_Store delete mode 100644 packages/cli/.gitignore delete mode 100644 packages/cli/.idea/angel_cli.iml delete mode 100644 packages/cli/.idea/modules.xml delete mode 100644 packages/cli/.idea/runConfigurations/Controller.xml delete mode 100644 packages/cli/.idea/runConfigurations/Doctor.xml delete mode 100644 packages/cli/.idea/runConfigurations/Init.xml delete mode 100644 packages/cli/.idea/runConfigurations/Show_Help.xml delete mode 100644 packages/cli/.idea/runConfigurations/Update.xml delete mode 100644 packages/cli/.idea/runConfigurations/Version.xml delete mode 100644 packages/cli/.travis.yml delete mode 100644 packages/cli/AUTHORS.md delete mode 100644 packages/cli/CHANGELOG.md delete mode 100644 packages/cli/LICENSE delete mode 100644 packages/cli/TODO.md delete mode 100644 packages/cli/analysis_options.yaml delete mode 100644 packages/cli/bin/angel.dart delete mode 100644 packages/cli/example/main.dart delete mode 100644 packages/cli/lib/angel_cli.dart delete mode 100644 packages/cli/lib/src/commands/commands.dart delete mode 100644 packages/cli/lib/src/commands/deploy.dart delete mode 100644 packages/cli/lib/src/commands/deploy/nginx.dart delete mode 100644 packages/cli/lib/src/commands/deploy/systemd.dart delete mode 100644 packages/cli/lib/src/commands/doctor.dart delete mode 100644 packages/cli/lib/src/commands/init.dart delete mode 100644 packages/cli/lib/src/commands/install.dart delete mode 100644 packages/cli/lib/src/commands/key.dart delete mode 100644 packages/cli/lib/src/commands/make.dart delete mode 100644 packages/cli/lib/src/commands/make/controller.dart delete mode 100644 packages/cli/lib/src/commands/make/maker.dart delete mode 100644 packages/cli/lib/src/commands/make/migration.dart delete mode 100644 packages/cli/lib/src/commands/make/model.dart delete mode 100644 packages/cli/lib/src/commands/make/plugin.dart delete mode 100644 packages/cli/lib/src/commands/make/service.dart delete mode 100644 packages/cli/lib/src/commands/make/test.dart delete mode 100644 packages/cli/lib/src/commands/pub.dart delete mode 100644 packages/cli/lib/src/commands/rename.dart delete mode 100644 packages/cli/lib/src/commands/service_generators/custom.dart delete mode 100644 packages/cli/lib/src/commands/service_generators/file_service.dart delete mode 100644 packages/cli/lib/src/commands/service_generators/generator.dart delete mode 100644 packages/cli/lib/src/commands/service_generators/map.dart delete mode 100644 packages/cli/lib/src/commands/service_generators/mongo.dart delete mode 100644 packages/cli/lib/src/commands/service_generators/rethink.dart delete mode 100644 packages/cli/lib/src/commands/service_generators/service_generators.dart delete mode 100644 packages/cli/lib/src/random_string.dart delete mode 100644 packages/cli/lib/src/util.dart delete mode 100644 packages/cli/pubspec.yaml delete mode 100644 packages/cli/screenshots/screenshot.png delete mode 100644 packages/graphql/.gitignore delete mode 100644 packages/graphql/.idea/graphql_parser.iml delete mode 100644 packages/graphql/.idea/modules.xml delete mode 100644 packages/graphql/.idea/runConfigurations/main_dart.xml delete mode 100644 packages/graphql/.idea/runConfigurations/objects_in_equality_test_dart.xml delete mode 100644 packages/graphql/.idea/runConfigurations/server_dart.xml delete mode 100644 packages/graphql/.idea/runConfigurations/tests_in_comment_test_dart.xml delete mode 100644 packages/graphql/.idea/runConfigurations/tests_in_graphql_parser.xml delete mode 100644 packages/graphql/.idea/runConfigurations/tests_in_graphql_schema.xml delete mode 100644 packages/graphql/.idea/runConfigurations/tests_in_mirrors_test_dart.xml delete mode 100644 packages/graphql/.idea/runConfigurations/tests_in_query_test_dart.xml delete mode 100644 packages/graphql/.idea/runConfigurations/tests_in_validation_test_dart.xml delete mode 100644 packages/graphql/.idea/runConfigurations/tests_in_value_test_dart.xml delete mode 100644 packages/graphql/.idea/vcs.xml delete mode 100644 packages/graphql/.travis.yml delete mode 100644 packages/graphql/LICENSE delete mode 100644 packages/graphql/angel_graphql/.gitignore delete mode 100644 packages/graphql/angel_graphql/CHANGELOG.md delete mode 100644 packages/graphql/angel_graphql/LICENSE delete mode 100644 packages/graphql/angel_graphql/README.md delete mode 100644 packages/graphql/angel_graphql/analysis_options.yaml delete mode 100644 packages/graphql/angel_graphql/angel_graphql.iml delete mode 100644 packages/graphql/angel_graphql/example/main.dart delete mode 100644 packages/graphql/angel_graphql/example/subscription.dart delete mode 100644 packages/graphql/angel_graphql/lib/angel_graphql.dart delete mode 100644 packages/graphql/angel_graphql/lib/src/graphiql.dart delete mode 100644 packages/graphql/angel_graphql/lib/src/graphql_http.dart delete mode 100644 packages/graphql/angel_graphql/lib/src/graphql_ws.dart delete mode 100644 packages/graphql/angel_graphql/lib/src/resolvers.dart delete mode 100644 packages/graphql/angel_graphql/mono_pkg.yaml delete mode 100644 packages/graphql/angel_graphql/pubspec.yaml delete mode 100644 packages/graphql/data_loader/.gitignore delete mode 100644 packages/graphql/data_loader/CHANGELOG.md delete mode 100644 packages/graphql/data_loader/LICENSE delete mode 100644 packages/graphql/data_loader/README.md delete mode 100644 packages/graphql/data_loader/analysis_options.yaml delete mode 100644 packages/graphql/data_loader/example/main.dart delete mode 100644 packages/graphql/data_loader/lib/data_loader.dart delete mode 100644 packages/graphql/data_loader/mono_pkg.yaml delete mode 100644 packages/graphql/data_loader/pubspec.yaml delete mode 100644 packages/graphql/data_loader/test/all_test.dart delete mode 100644 packages/graphql/example_star_wars/.gitignore delete mode 100644 packages/graphql/example_star_wars/LICENSE delete mode 100644 packages/graphql/example_star_wars/analysis_options.yaml delete mode 100644 packages/graphql/example_star_wars/bin/server.dart delete mode 100644 packages/graphql/example_star_wars/example_star_wars.iml delete mode 100644 packages/graphql/example_star_wars/lib/src/models/character.dart delete mode 100644 packages/graphql/example_star_wars/lib/src/models/character.g.dart delete mode 100644 packages/graphql/example_star_wars/lib/src/models/droid.dart delete mode 100644 packages/graphql/example_star_wars/lib/src/models/droid.g.dart delete mode 100644 packages/graphql/example_star_wars/lib/src/models/episode.dart delete mode 100644 packages/graphql/example_star_wars/lib/src/models/episode.g.dart delete mode 100644 packages/graphql/example_star_wars/lib/src/models/human.dart delete mode 100644 packages/graphql/example_star_wars/lib/src/models/human.g.dart delete mode 100644 packages/graphql/example_star_wars/lib/src/models/models.dart delete mode 100644 packages/graphql/example_star_wars/lib/src/models/starship.dart delete mode 100644 packages/graphql/example_star_wars/lib/src/models/starship.g.dart delete mode 100644 packages/graphql/example_star_wars/lib/src/pretty_logging.dart delete mode 100644 packages/graphql/example_star_wars/lib/star_wars.dart delete mode 100644 packages/graphql/example_star_wars/mono_pkg.yaml delete mode 100644 packages/graphql/example_star_wars/pubspec.yaml delete mode 100644 packages/graphql/graphql.iml delete mode 100644 packages/graphql/graphql_generator/.gitignore delete mode 100644 packages/graphql/graphql_generator/CHANGELOG.md delete mode 100644 packages/graphql/graphql_generator/LICENSE delete mode 100644 packages/graphql/graphql_generator/README.md delete mode 100644 packages/graphql/graphql_generator/analysis_options.yaml delete mode 100644 packages/graphql/graphql_generator/build.yaml delete mode 100644 packages/graphql/graphql_generator/example/main.dart delete mode 100644 packages/graphql/graphql_generator/example/main.g.dart delete mode 100644 packages/graphql/graphql_generator/lib/graphql_generator.dart delete mode 100644 packages/graphql/graphql_generator/mono_pkg.yaml delete mode 100644 packages/graphql/graphql_generator/pubspec.yaml delete mode 100644 packages/graphql/graphql_parser/.gitignore delete mode 100644 packages/graphql/graphql_parser/CHANGELOG.md delete mode 100644 packages/graphql/graphql_parser/LICENSE delete mode 100644 packages/graphql/graphql_parser/README.md delete mode 100644 packages/graphql/graphql_parser/analysis_options.yaml delete mode 100644 packages/graphql/graphql_parser/example/example.dart delete mode 100644 packages/graphql/graphql_parser/graphql_parser.iml delete mode 100644 packages/graphql/graphql_parser/lib/graphql_parser.dart delete mode 100644 packages/graphql/graphql_parser/lib/src/language/ast/alias.dart delete mode 100644 packages/graphql/graphql_parser/lib/src/language/ast/argument.dart delete mode 100644 packages/graphql/graphql_parser/lib/src/language/ast/array_value.dart delete mode 100644 packages/graphql/graphql_parser/lib/src/language/ast/ast.dart delete mode 100644 packages/graphql/graphql_parser/lib/src/language/ast/boolean_value.dart delete mode 100644 packages/graphql/graphql_parser/lib/src/language/ast/default_value.dart delete mode 100644 packages/graphql/graphql_parser/lib/src/language/ast/definition.dart delete mode 100644 packages/graphql/graphql_parser/lib/src/language/ast/deprecated_value.dart delete mode 100644 packages/graphql/graphql_parser/lib/src/language/ast/directive.dart delete mode 100644 packages/graphql/graphql_parser/lib/src/language/ast/document.dart delete mode 100644 packages/graphql/graphql_parser/lib/src/language/ast/field.dart delete mode 100644 packages/graphql/graphql_parser/lib/src/language/ast/field_name.dart delete mode 100644 packages/graphql/graphql_parser/lib/src/language/ast/fragment_definition.dart delete mode 100644 packages/graphql/graphql_parser/lib/src/language/ast/fragment_spread.dart delete mode 100644 packages/graphql/graphql_parser/lib/src/language/ast/inline_fragment.dart delete mode 100644 packages/graphql/graphql_parser/lib/src/language/ast/input_value.dart delete mode 100644 packages/graphql/graphql_parser/lib/src/language/ast/list_type.dart delete mode 100644 packages/graphql/graphql_parser/lib/src/language/ast/misc_value.dart delete mode 100644 packages/graphql/graphql_parser/lib/src/language/ast/node.dart delete mode 100644 packages/graphql/graphql_parser/lib/src/language/ast/number_value.dart delete mode 100644 packages/graphql/graphql_parser/lib/src/language/ast/operation_definition.dart delete mode 100644 packages/graphql/graphql_parser/lib/src/language/ast/selection.dart delete mode 100644 packages/graphql/graphql_parser/lib/src/language/ast/selection_set.dart delete mode 100644 packages/graphql/graphql_parser/lib/src/language/ast/string_value.dart delete mode 100644 packages/graphql/graphql_parser/lib/src/language/ast/type.dart delete mode 100644 packages/graphql/graphql_parser/lib/src/language/ast/type_condition.dart delete mode 100644 packages/graphql/graphql_parser/lib/src/language/ast/type_name.dart delete mode 100644 packages/graphql/graphql_parser/lib/src/language/ast/variable.dart delete mode 100644 packages/graphql/graphql_parser/lib/src/language/ast/variable_definition.dart delete mode 100644 packages/graphql/graphql_parser/lib/src/language/ast/variable_definitions.dart delete mode 100644 packages/graphql/graphql_parser/lib/src/language/language.dart delete mode 100644 packages/graphql/graphql_parser/lib/src/language/lexer.dart delete mode 100644 packages/graphql/graphql_parser/lib/src/language/parser.dart delete mode 100644 packages/graphql/graphql_parser/lib/src/language/syntax_error.dart delete mode 100644 packages/graphql/graphql_parser/lib/src/language/token.dart delete mode 100644 packages/graphql/graphql_parser/lib/src/language/token_type.dart delete mode 100644 packages/graphql/graphql_parser/mono_pkg.yaml delete mode 100644 packages/graphql/graphql_parser/pubspec.yaml delete mode 100644 packages/graphql/graphql_parser/test/argument_test.dart delete mode 100644 packages/graphql/graphql_parser/test/comment_test.dart delete mode 100644 packages/graphql/graphql_parser/test/common.dart delete mode 100644 packages/graphql/graphql_parser/test/directive_test.dart delete mode 100644 packages/graphql/graphql_parser/test/document_test.dart delete mode 100644 packages/graphql/graphql_parser/test/field_test.dart delete mode 100644 packages/graphql/graphql_parser/test/fragment_spread_test.dart delete mode 100644 packages/graphql/graphql_parser/test/inline_fragment_test.dart delete mode 100644 packages/graphql/graphql_parser/test/issue23_test.dart delete mode 100644 packages/graphql/graphql_parser/test/next_name_test.dart delete mode 100644 packages/graphql/graphql_parser/test/selection_set_test.dart delete mode 100644 packages/graphql/graphql_parser/test/type_test.dart delete mode 100644 packages/graphql/graphql_parser/test/value_test.dart delete mode 100644 packages/graphql/graphql_parser/test/variable_definition_test.dart delete mode 100644 packages/graphql/graphql_parser/test/variable_test.dart delete mode 100644 packages/graphql/graphql_schema/.gitignore delete mode 100644 packages/graphql/graphql_schema/CHANGELOG.md delete mode 100644 packages/graphql/graphql_schema/LICENSE delete mode 100644 packages/graphql/graphql_schema/README.md delete mode 100644 packages/graphql/graphql_schema/analysis_options.yaml delete mode 100644 packages/graphql/graphql_schema/example/example.dart delete mode 100644 packages/graphql/graphql_schema/graphql_schema.iml delete mode 100644 packages/graphql/graphql_schema/lib/graphql_schema.dart delete mode 100644 packages/graphql/graphql_schema/lib/src/argument.dart delete mode 100644 packages/graphql/graphql_schema/lib/src/enum.dart delete mode 100644 packages/graphql/graphql_schema/lib/src/field.dart delete mode 100644 packages/graphql/graphql_schema/lib/src/gen.dart delete mode 100644 packages/graphql/graphql_schema/lib/src/object_type.dart delete mode 100644 packages/graphql/graphql_schema/lib/src/scalar.dart delete mode 100644 packages/graphql/graphql_schema/lib/src/schema.dart delete mode 100644 packages/graphql/graphql_schema/lib/src/type.dart delete mode 100644 packages/graphql/graphql_schema/lib/src/union.dart delete mode 100644 packages/graphql/graphql_schema/lib/src/validation_result.dart delete mode 100644 packages/graphql/graphql_schema/mono_pkg.yaml delete mode 100644 packages/graphql/graphql_schema/pubspec.yaml delete mode 100644 packages/graphql/graphql_schema/test/common.dart delete mode 100644 packages/graphql/graphql_schema/test/equality_test.dart delete mode 100644 packages/graphql/graphql_schema/test/inheritance_test.dart delete mode 100644 packages/graphql/graphql_schema/test/serialize_test.dart delete mode 100644 packages/graphql/graphql_schema/test/validation_test.dart delete mode 100644 packages/graphql/graphql_server/.gitignore delete mode 100644 packages/graphql/graphql_server/CHANGELOG.md delete mode 100644 packages/graphql/graphql_server/LICENSE delete mode 100644 packages/graphql/graphql_server/README.md delete mode 100644 packages/graphql/graphql_server/analysis_options.yaml delete mode 100644 packages/graphql/graphql_server/example/main.dart delete mode 100644 packages/graphql/graphql_server/graphql_server.iml delete mode 100644 packages/graphql/graphql_server/lib/graphql_server.dart delete mode 100644 packages/graphql/graphql_server/lib/introspection.dart delete mode 100644 packages/graphql/graphql_server/lib/mirrors.dart delete mode 100644 packages/graphql/graphql_server/lib/src/apollo/remote_client.dart delete mode 100644 packages/graphql/graphql_server/lib/src/apollo/server.dart delete mode 100644 packages/graphql/graphql_server/lib/src/apollo/transport.dart delete mode 100644 packages/graphql/graphql_server/lib/subscriptions_transport_ws.dart delete mode 100644 packages/graphql/graphql_server/mono_pkg.yaml delete mode 100644 packages/graphql/graphql_server/pubspec.yaml delete mode 100644 packages/graphql/graphql_server/test/common.dart delete mode 100644 packages/graphql/graphql_server/test/mirrors_test.dart delete mode 100644 packages/graphql/graphql_server/test/query_test.dart delete mode 100644 packages/graphql/graphql_server/test/subscription_test.dart delete mode 100644 packages/graphql/img/angel_graphql.png delete mode 100644 packages/graphql/img/angel_logo.png delete mode 100644 packages/graphql/img/angel_logo.xcf delete mode 100644 packages/graphql/travis.sh delete mode 100644 packages/graphql/video.png diff --git a/packages/cli/.DS_Store b/packages/cli/.DS_Store deleted file mode 100644 index 5d196f037d56ca0b78267e0adb31afd97123cb69..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHK!AiqG5Pj1Y(xQhRJ?7}C;2*@A2nDs!`T?3mL5M~uJ$TD!_)-3ozS&($lGdwW znStH6J3DVD`xbVy0A#)`FMuh4F^l40!s>wOxRyN|1W!a1oue-Ds?OQd>CFCv0=joY z z{Gbi-2?b{Oz$0E!b$QS%pRLcEV8slVNO4P?kx_OTE>oKk;T}uIFAqh7%a?I$ex@@s z1xx``;8+yUBb+uq@o2RvU<#N5I|cN7h*=bqfQ?6Ybg*(y0OE*lXKcHle`2f-ViK_N zNDoasmFTGwo){9|4&vz?PeOd-(bFL=Gv^7JCA?51JUt|K;gH0m)uw(CkOR$zYW!@TUs=0QneOR{#J2 diff --git a/packages/cli/.gitignore b/packages/cli/.gitignore deleted file mode 100644 index b0dcebde..00000000 --- a/packages/cli/.gitignore +++ /dev/null @@ -1,80 +0,0 @@ -# Created by .ignore support plugin (hsz.mobi) -### JetBrains template -# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm -# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 - -# User-specific stuff: -.idea/workspace.xml -.idea/tasks.xml -.idea/dictionaries -.idea/vcs.xml -.idea/jsLibraryMappings.xml - -# Sensitive or high-churn files: -.idea/dataSources.ids -.idea/dataSources.xml -.idea/dataSources.local.xml -.idea/sqlDataSources.xml -.idea/dynamic.xml -.idea/uiDesigner.xml - -# Gradle: -.idea/gradle.xml -.idea/libraries - -# Mongo Explorer plugin: -.idea/mongoSettings.xml - -## File-based project format: -*.iws - -## Plugin-specific files: - -# IntelliJ -/out/ - -# mpeltonen/sbt-idea plugin -.idea_modules/ - -# JIRA plugin -atlassian-ide-plugin.xml - -# Crashlytics plugin (for Android Studio and IntelliJ) -com_crashlytics_export_strings.xml -crashlytics.properties -crashlytics-build.properties -fabric.properties -### Dart template -# See https://www.dartlang.org/tools/private-files.html - -# Files and directories created by pub -.buildlog -.packages -.project -.pub/ -build/ -**/packages/ - -# Files created by dart2js -# (Most Dart developers will use pub build to compile Dart, use/modify these -# rules if you intend to use dart2js directly -# Convention is to use extension '.dart.js' for Dart compiled to Javascript to -# differentiate from explicit Javascript files) -*.dart.js -*.part.js -*.js.deps -*.js.map -*.info.json - -# Directory created by dartdoc -doc/api/ - -# Don't commit pubspec lock file -# (Library packages only! Remove pattern if developing an application package) -pubspec.lock -/sample_project/lib/src/services/ -/sample_project/test/services/ -/sample_project/ -sample_project/ -sample-project -.dart_tool \ No newline at end of file diff --git a/packages/cli/.idea/angel_cli.iml b/packages/cli/.idea/angel_cli.iml deleted file mode 100644 index 6118a7ae..00000000 --- a/packages/cli/.idea/angel_cli.iml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/packages/cli/.idea/modules.xml b/packages/cli/.idea/modules.xml deleted file mode 100644 index 5f91449b..00000000 --- a/packages/cli/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/packages/cli/.idea/runConfigurations/Controller.xml b/packages/cli/.idea/runConfigurations/Controller.xml deleted file mode 100644 index 38315109..00000000 --- a/packages/cli/.idea/runConfigurations/Controller.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - \ No newline at end of file diff --git a/packages/cli/.idea/runConfigurations/Doctor.xml b/packages/cli/.idea/runConfigurations/Doctor.xml deleted file mode 100644 index bd640ddb..00000000 --- a/packages/cli/.idea/runConfigurations/Doctor.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - \ No newline at end of file diff --git a/packages/cli/.idea/runConfigurations/Init.xml b/packages/cli/.idea/runConfigurations/Init.xml deleted file mode 100644 index c0740078..00000000 --- a/packages/cli/.idea/runConfigurations/Init.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - \ No newline at end of file diff --git a/packages/cli/.idea/runConfigurations/Show_Help.xml b/packages/cli/.idea/runConfigurations/Show_Help.xml deleted file mode 100644 index 009fef31..00000000 --- a/packages/cli/.idea/runConfigurations/Show_Help.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - \ No newline at end of file diff --git a/packages/cli/.idea/runConfigurations/Update.xml b/packages/cli/.idea/runConfigurations/Update.xml deleted file mode 100644 index 75cab2d3..00000000 --- a/packages/cli/.idea/runConfigurations/Update.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - \ No newline at end of file diff --git a/packages/cli/.idea/runConfigurations/Version.xml b/packages/cli/.idea/runConfigurations/Version.xml deleted file mode 100644 index cd70052b..00000000 --- a/packages/cli/.idea/runConfigurations/Version.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - \ No newline at end of file diff --git a/packages/cli/.travis.yml b/packages/cli/.travis.yml deleted file mode 100644 index 3939d628..00000000 --- a/packages/cli/.travis.yml +++ /dev/null @@ -1 +0,0 @@ -language: dart diff --git a/packages/cli/AUTHORS.md b/packages/cli/AUTHORS.md deleted file mode 100644 index 2a973de6..00000000 --- a/packages/cli/AUTHORS.md +++ /dev/null @@ -1,2 +0,0 @@ -Tobe O -Thomas Hii \ No newline at end of file diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md deleted file mode 100644 index 874c8d7f..00000000 --- a/packages/cli/CHANGELOG.md +++ /dev/null @@ -1,92 +0,0 @@ -# 3.0.0 -* Migrated to work with Dart SDK 2.12.x Non NNBD - -# 2.1.7+1 -* Fix a bug where new directories were not being created in -`init`. - -# 2.1.7 -* Fix a bug where `ArgResults.arguments` was used in `init` instead of the -intended `ArgResults.rest`. -* Stop including `package:angel_model` imports in `make model`. -* Update dependencies in `make` commands. -* Fix `make model` to generate ORM + migration by default. -* Fix `MakerDependency` logic to print missing dependencies. - -# 2.1.6 -* Fix a bug where models always defaulted to ORM. -* Add GraphQL boilerplate. -* Automatically restore terminal colors on shutdown. - -# 2.1.5+1 -* Update to `inflection2`. - -# 2.1.5 -* Add `shared` boilerplates. -* Remove uncecessary `angel_model` imports. - -# 2.1.4+1 -* Patch `part of 'path'` renames. - -# 2.1.4 -* The `migration` argument to `model` just emits an annotation now. -* Add the ORM boilerplate. - -# 2.1.3 -* Fix generation of ORM models. -* A `--project-name` to `init` command. - -# 2.1.2 -* No migrations-by-default. - -# 2.1.1 -* Edit the way `rename` runs, leaving no corner unturned. - -# 2.1.0 -* Deprecate `angel install`. -* Rename projects using `snake_case`. -* `init` now fetches from `master`. -* Remove the `1.x` option. -* Add `make migration` command. -* Replace `{{oldName}}` in the `rename` command. -* `pub get` now runs with `inheritStdio`. - -# 2.0.1 -* `deploy systemd` now has an `--install` option, where you can immediately -spawn the service. - -# 2.0.0 -* `init` can now produce either 1.x or 2.x projects. -* Fixed deps for compatibility with Dart2 stable. - -# 1.3.4 -* Fix another typo. - -# 1.3.3 -* Fix a small typo in the model generator. - -# 1.3.2 -* Restore `part` directives in generated models. - -# 1.3.1 -* Add `deploy nginx` and `deploy systemd`. - -# 1.3.0 -* Focus on Dart2 from here on out. -* Update `code_builder`. -* More changes... - -# 1.1.5 -Deprecated several commands, in favor of the `make` -command: -* `controller` -* `plugin` -* `service` -* `test` - -The `rename` command will now replace *all* occurrences -of the old project names with the new one in `config/` -YAML files, and also operates on the glob `config/**/*.yaml`. - -Changed the call to run `angel start` to run `dart bin/server.dart` instead, after an -`init` command. diff --git a/packages/cli/LICENSE b/packages/cli/LICENSE deleted file mode 100644 index 63b4b681..00000000 --- a/packages/cli/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) [year] [fullname] - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file diff --git a/packages/cli/README.md b/packages/cli/README.md index 1aaea509..fdc51728 100644 --- a/packages/cli/README.md +++ b/packages/cli/README.md @@ -1,26 +1,3 @@ -# angel_cli +# Angel3 CLI -![Screenshot of Terminal](screenshots/screenshot.png) - -Command-line tools for the Angel framework. -Includes functionality such as: -* Project scaffolding -* Generating service models, plugins, tests and more -* Renaming projects -* Much more... - -* To install: - -```bash -$ pub global activate angel_cli -``` - -* Install development version -`dart pub global activate --source path ./packages/cli` -`dart pub global activate --source git https://github.com/dukefirehawk/angel/packages/cli` - -And then, for information on each command: - -```bash -$ angel help -``` +Moved to [`Angel3 CLI Repo`](https://github.com/dukefirehawk/angel3-cli) \ No newline at end of file diff --git a/packages/cli/TODO.md b/packages/cli/TODO.md deleted file mode 100644 index 868ba85c..00000000 --- a/packages/cli/TODO.md +++ /dev/null @@ -1,8 +0,0 @@ -# Todo -* Migrate inflection2, mustache4dart2 and prompts packages to NNBD - -* `service` - * Add tests -* `migration` -* `deploy` -* Call these from Grinder script :) \ No newline at end of file diff --git a/packages/cli/analysis_options.yaml b/packages/cli/analysis_options.yaml deleted file mode 100644 index eae1e42a..00000000 --- a/packages/cli/analysis_options.yaml +++ /dev/null @@ -1,3 +0,0 @@ -analyzer: - strong-mode: - implicit-casts: false \ No newline at end of file diff --git a/packages/cli/bin/angel.dart b/packages/cli/bin/angel.dart deleted file mode 100644 index 43c62d82..00000000 --- a/packages/cli/bin/angel.dart +++ /dev/null @@ -1,55 +0,0 @@ -#!/usr/bin/env dart -library angel_cli.tool; - -import "dart:io"; -import "package:args/command_runner.dart"; -import 'package:angel_cli/angel_cli.dart'; -import 'package:io/ansi.dart'; - -final String DOCTOR = "doctor"; - -main(List args) async { - var runner = new CommandRunner( - "angel", - asciiArt.trim() + - '\n\n' + - "Command-line tools for the Angel framework." + - '\n\n' + - 'https://angel-dart.github.io'); - - runner.argParser - .addFlag('verbose', help: 'Print verbose output.', negatable: false); - - runner - ..addCommand(new DeployCommand()) - ..addCommand(new DoctorCommand()) - ..addCommand(new KeyCommand()) - ..addCommand(new InitCommand()) - ..addCommand(new InstallCommand()) - ..addCommand(new RenameCommand()) - ..addCommand(new MakeCommand()); - - return await runner.run(args).catchError((exc, st) { - if (exc is String) { - stdout.writeln(exc); - } else { - stderr.writeln("Oops, something went wrong: $exc"); - if (args.contains('--verbose')) { - stderr.writeln(st); - } - } - - exitCode = 1; - }).whenComplete(() { - stdout.write(resetAll.wrap('')); - }); -} - -const String asciiArt = ''' -____________ ________________________ -___ |__ | / /_ ____/__ ____/__ / -__ /| |_ |/ /_ / __ __ __/ __ / -_ ___ | /| / / /_/ / _ /___ _ /___ -/_/ |_/_/ |_/ \____/ /_____/ /_____/ - -'''; diff --git a/packages/cli/example/main.dart b/packages/cli/example/main.dart deleted file mode 100644 index ffecc0d0..00000000 --- a/packages/cli/example/main.dart +++ /dev/null @@ -1,3 +0,0 @@ -void main() { - // This package isn't usable from code. -} diff --git a/packages/cli/lib/angel_cli.dart b/packages/cli/lib/angel_cli.dart deleted file mode 100644 index 843a6734..00000000 --- a/packages/cli/lib/angel_cli.dart +++ /dev/null @@ -1,3 +0,0 @@ -library angel_cli; - -export 'src/commands/commands.dart'; diff --git a/packages/cli/lib/src/commands/commands.dart b/packages/cli/lib/src/commands/commands.dart deleted file mode 100644 index a6db230d..00000000 --- a/packages/cli/lib/src/commands/commands.dart +++ /dev/null @@ -1,9 +0,0 @@ -library angel_cli.commands; - -export "deploy.dart"; -export "doctor.dart"; -export "key.dart"; -export "init.dart"; -export "install.dart"; -export "make.dart"; -export "rename.dart"; diff --git a/packages/cli/lib/src/commands/deploy.dart b/packages/cli/lib/src/commands/deploy.dart deleted file mode 100644 index 9c95ea50..00000000 --- a/packages/cli/lib/src/commands/deploy.dart +++ /dev/null @@ -1,17 +0,0 @@ -import 'package:args/command_runner.dart'; -import 'deploy/nginx.dart'; -import 'deploy/systemd.dart'; - -class DeployCommand extends Command { - @override - String get name => 'deploy'; - - @override - String get description => - 'Generates scaffolding + helper functionality for deploying servers. Run this in your project root.'; - - DeployCommand() { - addSubcommand(NginxCommand()); - addSubcommand(SystemdCommand()); - } -} diff --git a/packages/cli/lib/src/commands/deploy/nginx.dart b/packages/cli/lib/src/commands/deploy/nginx.dart deleted file mode 100644 index 638f70ac..00000000 --- a/packages/cli/lib/src/commands/deploy/nginx.dart +++ /dev/null @@ -1,52 +0,0 @@ -import 'dart:io'; -import 'package:args/command_runner.dart'; -import 'package:io/ansi.dart'; -import 'package:path/path.dart' as p; -import '../../util.dart'; - -class NginxCommand extends Command { - @override - String get name => 'nginx'; - - @override - String get description => - 'Generates a NGINX configuration for a reverse proxy + static server.'; - - NginxCommand() { - argParser.addOption('out', - abbr: 'o', - help: - 'An optional output file to write to; otherwise prints to stdout.'); - } - - @override - run() async { - var webPath = p.join(p.current, 'web'); - var nginxText = ''' -server { - listen 80 default_server; - root ${p.absolute(webPath)}; # Set to your static files directory - - location / { - try_files \$uri @proxy; # Try to serve static files; fallback to proxied Angel server - } - - location @proxy { - proxy_pass http://127.0.0.1:3000; - proxy_http_version 1.1; # Important, do not omit - } -} - ''' - .trim(); - - if (!argResults.wasParsed('out')) { - print(nginxText); - } else { - var file = new File(argResults['out'] as String); - await file.create(recursive: true); - await file.writeAsString(nginxText); - print(green.wrap( - "$checkmark Successfully generated nginx configuration in '${file.path}'.")); - } - } -} diff --git a/packages/cli/lib/src/commands/deploy/systemd.dart b/packages/cli/lib/src/commands/deploy/systemd.dart deleted file mode 100644 index 28c496a8..00000000 --- a/packages/cli/lib/src/commands/deploy/systemd.dart +++ /dev/null @@ -1,86 +0,0 @@ -import 'dart:io'; -import 'package:args/command_runner.dart'; -import 'package:io/ansi.dart'; -import 'package:path/path.dart' as p; -import '../../util.dart'; - -class SystemdCommand extends Command { - @override - String get name => 'systemd'; - - @override - String get description => - 'Generates a systemd service to continuously run your server.'; - - SystemdCommand() { - argParser - ..addOption('install', - abbr: 'i', help: 'A name to install this service as on the system.') - ..addOption('user', - abbr: 'u', - defaultsTo: 'web', - help: 'The name of the unprivileged account to run the server as.') - ..addOption('out', - abbr: 'o', - help: - 'An optional output file to write to; otherwise prints to stdout.'); - } - - @override - run() async { - var projectPath = p.absolute(p.current); - var pubspec = await loadPubspec(); - var user = argResults['user']; - var systemdText = ''' -[Unit] -Description=`${pubspec.name}` server - -[Service] -Environment=ANGEL_ENV=production -User=$user # Name of unprivileged `$user` user -WorkingDirectory=$projectPath # Path to `${pubspec.name}` project -ExecStart=${Platform.resolvedExecutable} bin/prod.dart -Restart=always # Restart process on crash - -[Install] -WantedBy=multi-user.target - ''' - .trim(); - - if (!argResults.wasParsed('out') && !argResults.wasParsed('install')) { - print(systemdText); - } else if (argResults.wasParsed('install')) { - var systemdPath = argResults.wasParsed('out') - ? argResults['out'] as String - : p.join('etc', 'systemd', 'system'); - var serviceFilename = p.join(systemdPath, - p.setExtension(argResults['install'] as String, '.service')); - var file = new File(serviceFilename); - await file.create(recursive: true); - await file.writeAsString(systemdText); - print(green.wrap( - "$checkmark Successfully generated systemd service in '${file.path}'.")); - - // sudo systemctl daemon-reload - if (await runCommand('sudo', ['systemctl', 'daemon-reload'])) { - // sudo service start - if (await runCommand('sudo', [ - 'service', - p.basenameWithoutExtension(serviceFilename), - 'start' - ])) { - } else { - print(red.wrap('$ballot Failed to install service system-wide.')); - } - } else { - print(red.wrap('$ballot Failed to install service system-wide.')); - } - } else { - var file = new File(argResults['out'] as String); - await file.create(recursive: true); - await file.writeAsString(systemdText); - print(green.wrap( - "$checkmark Successfully generated systemd service in '${file.path}'.")); - } - } -} diff --git a/packages/cli/lib/src/commands/doctor.dart b/packages/cli/lib/src/commands/doctor.dart deleted file mode 100644 index fc70af3f..00000000 --- a/packages/cli/lib/src/commands/doctor.dart +++ /dev/null @@ -1,34 +0,0 @@ -import "dart:convert"; -import "dart:io"; -import "package:args/command_runner.dart"; -import 'package:io/ansi.dart'; -import '../util.dart'; - -class DoctorCommand extends Command { - @override - String get name => "doctor"; - - @override - String get description => - "Ensures that the current system is capable of running Angel."; - - @override - run() async { - print("Checking your system for dependencies..."); - await _checkForGit(); - } - - _checkForGit() async { - try { - var git = await Process.start("git", ["--version"]); - if (await git.exitCode == 0) { - var version = await git.stdout.transform(utf8.decoder).join(); - print(green.wrap( - "$checkmark Git executable found: v${version.replaceAll('git version', '').trim()}")); - } else - throw Exception("Git executable exit code not 0"); - } catch (exc) { - print(red.wrap("$ballot Git executable not found")); - } - } -} diff --git a/packages/cli/lib/src/commands/init.dart b/packages/cli/lib/src/commands/init.dart deleted file mode 100644 index 92f2adec..00000000 --- a/packages/cli/lib/src/commands/init.dart +++ /dev/null @@ -1,324 +0,0 @@ -import 'dart:async'; -import "dart:io"; -import "package:args/command_runner.dart"; -import 'package:io/ansi.dart'; -import 'package:path/path.dart' as p; -import 'package:prompts/prompts.dart' as prompts; -import 'package:recase/recase.dart'; -import '../random_string.dart' as rs; -import '../util.dart'; -import 'key.dart'; -import 'pub.dart'; -import 'rename.dart'; - -class InitCommand extends Command { - final KeyCommand _key = KeyCommand(); - - @override - String get name => "init"; - - @override - String get description => - "Initializes a new Angel project in the current directory."; - - InitCommand() { - argParser - ..addFlag('offline', - help: - 'Disable online fetching of boilerplates. Also disables `pub-get`.', - negatable: false) - ..addFlag('pub-get', defaultsTo: true) - ..addOption('project-name', - abbr: 'n', help: 'The name for this project.'); - } - - @override - run() async { - Directory projectDir = - Directory(argResults.rest.isEmpty ? "." : argResults.rest[0]); - print("Creating new Angel project in ${projectDir.absolute.path}..."); - await _cloneRepo(projectDir); - // await preBuild(projectDir); - var secret = rs.randomAlphaNumeric(32); - print('Generated new development JWT secret: $secret'); - await _key.changeSecret( - File.fromUri(projectDir.uri.resolve('config/default.yaml')), secret); - - secret = rs.randomAlphaNumeric(32); - print('Generated new production JWT secret: $secret'); - await _key.changeSecret( - File.fromUri(projectDir.uri.resolve('config/production.yaml')), secret); - - var name = argResults.wasParsed('project-name') - ? argResults['project-name'] as String - : p.basenameWithoutExtension( - projectDir.absolute.uri.normalizePath().toFilePath()); - - name = ReCase(name).snakeCase; - print('Renaming project from "angel" to "$name"...'); - await renamePubspec(projectDir, 'angel', name); - await renameDartFiles(projectDir, 'angel', name); - - if (argResults['pub-get'] != false && argResults['offline'] == false) { - print('Now running pub get...'); - await _pubGet(projectDir); - } - - print(green.wrap("$checkmark Successfully initialized Angel project.")); - - stdout - ..writeln() - ..writeln( - 'Congratulations! You are ready to start developing with Angel!') - ..write('To start the server (with ') - ..write(cyan.wrap('hot-reloading')) - ..write('), run ') - ..write(magenta.wrap('`dart --observe bin/dev.dart`')) - ..writeln(' in your terminal.') - ..writeln() - ..writeln('Find more documentation about Angel:') - ..writeln(' * https://angel-dart.github.io') - ..writeln(' * https://github.com/angel-dart/angel/wiki') - ..writeln( - ' * https://www.youtube.com/playlist?list=PLl3P3tmiT-frEV50VdH_cIrA2YqIyHkkY') - ..writeln(' * https://medium.com/the-angel-framework') - ..writeln(' * https://dart.academy/tag/angel') - ..writeln() - ..writeln('Happy coding!'); - } - - _deleteRecursive(FileSystemEntity entity, [bool self = true]) async { - if (entity is Directory) { - await for (var entity in entity.list(recursive: true)) { - try { - await _deleteRecursive(entity); - } catch (e) {} - } - - try { - if (self != false) await entity.delete(recursive: true); - } catch (e) {} - } else if (entity is File) { - try { - await entity.delete(recursive: true); - } catch (e) {} - } else if (entity is Link) { - var path = await entity.resolveSymbolicLinks(); - var stat = await FileStat.stat(path); - - switch (stat.type) { - case FileSystemEntityType.directory: - return await _deleteRecursive(Directory(path)); - case FileSystemEntityType.file: - return await _deleteRecursive(File(path)); - default: - break; - } - } - } - - _cloneRepo(Directory projectDir) async { - Directory boilerplateDir; - - try { - if (await projectDir.exists()) { - var shouldDelete = prompts.getBool( - "Directory '${projectDir.absolute.path}' already exists. Overwrite it?"); - - if (!shouldDelete) - throw "Chose not to overwrite existing directory."; - else if (projectDir.absolute.uri.normalizePath().toFilePath() != - Directory.current.absolute.uri.normalizePath().toFilePath()) - await projectDir.delete(recursive: true); - else { - await _deleteRecursive(projectDir, false); - } - } - - // var boilerplate = basicBoilerplate; - print('Choose a project type before continuing:'); - var boilerplate = prompts.choose( - 'Choose a project type before continuing', boilerplates); - - // Ultimately, we want a clone of every boilerplate locally on the system. - var boilerplateRootDir = Directory(p.join(angelDir.path, 'boilerplates')); - var boilerplateBasename = p.basenameWithoutExtension(boilerplate.url); - if (boilerplate.ref != null) boilerplateBasename += '.${boilerplate.ref}'; - boilerplateDir = - Directory(p.join(boilerplateRootDir.path, boilerplateBasename)); - await boilerplateRootDir.create(recursive: true); - - var branch = boilerplate.ref ?? 'master'; - - // If there is no clone existing, clone it. - if (!await boilerplateDir.exists()) { - if (argResults['offline'] as bool) { - throw Exception( - '--offline was selected, but the "${boilerplate.name}" boilerplate has not yet been downloaded.'); - } - - print( - 'Cloning "${boilerplate.name}" boilerplate from "${boilerplate.url}"...'); - Process git; - - if (boilerplate.ref == null) { - print(darkGray.wrap( - '\$ git clone --depth 1 ${boilerplate.url} ${boilerplateDir.absolute.path}')); - git = await Process.start( - "git", - [ - "clone", - "--depth", - "1", - boilerplate.url, - boilerplateDir.absolute.path - ], - mode: ProcessStartMode.inheritStdio, - ); - } else { - // git clone --single-branch -b branch host:/dir.git - print(darkGray.wrap( - '\$ git clone --depth 1 --single-branch -b ${boilerplate.ref} ${boilerplate.url} ${boilerplateDir.absolute.path}')); - git = await Process.start( - "git", - [ - "clone", - "--depth", - "1", - "--single-branch", - "-b", - boilerplate.ref, - boilerplate.url, - boilerplateDir.absolute.path - ], - mode: ProcessStartMode.inheritStdio, - ); - } - - if (await git.exitCode != 0) { - throw Exception("Could not clone repo."); - } - } - - // Otherwise, pull from git. - else if (!(argResults['offline'] as bool)) { - print(darkGray.wrap('\$ git pull origin $branch')); - var git = await Process.start("git", ['pull', 'origin', '$branch'], - mode: ProcessStartMode.inheritStdio, - workingDirectory: boilerplateDir.absolute.path); - if (await git.exitCode != 0) { - print(yellow.wrap( - "Update of $branch failed. Attempting to continue with existing contents.")); - } - } else { - print(darkGray.wrap( - 'Using existing contents of "${boilerplate.name}" boilerplate.')); - } - - // Next, just copy everything into the given directory. - await copyDirectory(boilerplateDir, projectDir); - - if (boilerplate.needsPrebuild) { - await preBuild(projectDir).catchError((_) => null); - } - - var gitDir = Directory.fromUri(projectDir.uri.resolve(".git")); - if (await gitDir.exists()) await gitDir.delete(recursive: true); - } catch (e) { - await boilerplateDir.delete(recursive: true).catchError((_) => null); - - if (e is! String) { - print(red.wrap("$ballot Could not initialize Angel project.")); - } - rethrow; - } - } - - _pubGet(Directory projectDir) async { - var pubPath = resolvePub(); - print(darkGray.wrap('Running pub at "$pubPath"...')); - print(darkGray.wrap('\$ $pubPath get')); - var pub = await Process.start(pubPath, ["get"], - workingDirectory: projectDir.absolute.path, - mode: ProcessStartMode.inheritStdio); - var code = await pub.exitCode; - print("Pub process exited with code $code"); - } -} - -Future preBuild(Directory projectDir) async { - // Run build - // print('Running `pub run build_runner build`...'); - print(darkGray.wrap('\$ pub run build_runner build')); - - var build = await Process.start( - resolvePub(), ['run', 'build_runner', 'build'], - workingDirectory: projectDir.absolute.path, - mode: ProcessStartMode.inheritStdio); - - var buildCode = await build.exitCode; - - if (buildCode != 0) throw Exception('Failed to pre-build resources.'); -} - -const RepoArchiveLocation = "https://github.com/angel-dart"; -const RepoLocation = "https://github.com/dukefirehawk"; - -const BoilerplateInfo graphQLBoilerplate = const BoilerplateInfo( - 'GraphQL', - "A starting point for GraphQL API servers.", - '${RepoLocation}/boilerplates.git', - ref: 'graphql-sdk-2.12.x', -); - -const BoilerplateInfo ormBoilerplate = const BoilerplateInfo( - 'ORM', - "A starting point for applications that use Angel's ORM.", - '${RepoLocation}/boilerplates.git', - ref: 'orm-sdk-2.12.x', -); - -const BoilerplateInfo basicBoilerplate = const BoilerplateInfo( - 'Basic', - 'Minimal starting point for Angel 2.x - A simple server with only a few additional packages.', - '${RepoLocation}/boilerplates.git', - ref: 'basic-sdk-2.12.x'); - -const BoilerplateInfo legacyBoilerplate = const BoilerplateInfo( - 'Legacy', - 'Minimal starting point for applications running Angel 1.1.x.', - '${RepoArchiveLocation}/angel.git', - ref: '1.1.x', -); - -const BoilerplateInfo sharedBoilerplate = const BoilerplateInfo( - 'Shared', - 'Holds common models and files shared across multiple Dart projects.', - '${RepoLocation}/boilerplate_shared.git'); - -const BoilerplateInfo sharedOrmBoilerplate = const BoilerplateInfo( - 'Shared (ORM)', - 'Holds common models and files shared across multiple Dart projects.', - '${RepoLocation}/boilerplate_shared.git', - ref: 'orm', -); - -const List boilerplates = const [ - basicBoilerplate, - //legacyBoilerplate, - ormBoilerplate, - graphQLBoilerplate, - //sharedBoilerplate, - //sharedOrmBoilerplate, -]; - -class BoilerplateInfo { - final String name, description, url, ref; - final bool needsPrebuild; - - const BoilerplateInfo(this.name, this.description, this.url, - {this.ref, this.needsPrebuild: false}); - - @override - String toString() => '$name ($description)'; -} diff --git a/packages/cli/lib/src/commands/install.dart b/packages/cli/lib/src/commands/install.dart deleted file mode 100644 index 484fe120..00000000 --- a/packages/cli/lib/src/commands/install.dart +++ /dev/null @@ -1,247 +0,0 @@ -import 'dart:async'; -import 'dart:io'; -import 'package:args/command_runner.dart'; -import 'package:glob/glob.dart'; -import 'package:io/ansi.dart'; -import 'package:mustache4dart2/mustache4dart2.dart' as mustache; -import 'package:path/path.dart' as p; -import 'package:prompts/prompts.dart' as prompts; -import 'package:pubspec_parse/pubspec_parse.dart'; -import 'package:yaml/yaml.dart' as yaml; -import '../util.dart'; -import 'make/maker.dart'; - -class InstallCommand extends Command { - static const String repo = 'https://github.com/angel-dart/install.git'; - static final Directory installRepo = - Directory.fromUri(homeDir.uri.resolve('./.angel/addons')); - - @override - String get name => 'install'; - - @override - String get description => - 'Installs additional add-ons to minimize boilerplate.'; - - InstallCommand() { - argParser - ..addFlag( - 'list', - help: 'List all currently-installed add-ons.', - negatable: false, - defaultsTo: false, - ) - ..addFlag( - 'update', - help: 'Update the local add-on repository.', - negatable: false, - defaultsTo: false, - ) - ..addFlag( - 'wipe', - help: 'Wipe the local add-on repository.', - negatable: false, - defaultsTo: false, - ); - } - - @override - run() async { - print(yellow.wrap( - 'WARNING: The `install` command is no longer considered necessary, and has been deprecated.\n' - 'Expect it to be removed in an upcoming release.\n\n' - 'See here: https://github.com/angel-dart/install.git\n\n' - 'To stop seeing this, downgrade to `package:angel_cli@<=2.0.0`.')); - - if (argResults['wipe'] as bool) { - if (await installRepo.exists()) await installRepo.delete(recursive: true); - } else if (argResults['list'] as bool) { - var addons = await list(); - print('${addons.length} add-on(s) installed:'); - - for (var addon in addons) { - print(' * ${addon.name}@${addon.version}: ${addon.description}'); - } - } else if (argResults['update'] as bool) { - await update(); - } else if (argResults.rest.isNotEmpty) { - if (!await installRepo.exists()) - throw 'No local add-on database exists. Run `angel install --update` first.'; - - var pubspec = await loadPubspec(); - - for (var packageName in argResults.rest) { - var packageDir = - Directory.fromUri(installRepo.uri.resolve(packageName)); - - if (!await packageDir.exists()) - throw 'No add-on named "$packageName" is installed. You might need to run `angel install --update`.'; - print('Installing $packageName...'); - - Map values = { - 'project_name': pubspec.name, - 'pubspec': pubspec, - }; - - List globs = []; - - var projectPubspec = await loadPubspec(packageDir); - var deps = projectPubspec.dependencies.keys - .map((k) { - var dep = projectPubspec.dependencies[k]; - if (dep is HostedDependency) - return MakerDependency(k, dep.version.toString()); - return null; - }) - .where((d) => d != null) - .toList(); - - deps.addAll(projectPubspec.devDependencies.keys.map((k) { - var dep = projectPubspec.devDependencies[k]; - if (dep is HostedDependency) - return MakerDependency(k, dep.version.toString(), dev: true); - return null; - }).where((d) => d != null)); - - await depend(deps); - - var promptFile = File.fromUri(packageDir.uri.resolve('angel_cli.yaml')); - - if (await promptFile.exists()) { - var contents = await promptFile.readAsString(); - var y = yaml.loadYamlDocument(contents); - var cfg = y.contents.value as Map; - - // Loads globs - if (cfg['templates'] is List) { - globs.addAll( - (cfg['templates'] as List).map((p) => Glob(p.toString()))); - } - - if (cfg['values'] is Map) { - var val = cfg['values'] as Map; - - for (var key in val.keys) { - var desc = val[key]['description'] ?? key; - - if (val[key]['type'] == 'prompt') { - values[key] = prompts.get(desc.toString(), - defaultsTo: val[key]['default']?.toString()); - } else if (val[key]['type'] == 'choice') { - values[key] = prompts.choose( - desc.toString(), val[key]['choices'] as Iterable); - } - } - } - } - - Future merge(Directory src, Directory dst, String prefix) async { - if (!await src.exists()) return; - print('Copying ${src.absolute.path} into ${dst.absolute.path}...'); - if (!await dst.exists()) await dst.create(recursive: true); - - await for (var entity in src.list()) { - if (entity is Directory) { - var name = p.basename(entity.path); - var newDir = Directory.fromUri(dst.uri.resolve(name)); - await merge( - entity, newDir, prefix.isEmpty ? name : '$prefix/$name'); - } else if (entity is File && - !entity.path.endsWith('angel_cli.yaml')) { - var name = p.basename(entity.path); - var target = dst.uri.resolve(name); - var targetFile = File.fromUri(target); - bool allClear = !await targetFile.exists(); - - if (!allClear) { - print('The file ${entity.absolute.path} already exists.'); - allClear = prompts.getBool('Overwrite the existing file?'); - if (allClear) await targetFile.delete(); - } - - if (allClear) { - try { - var path = prefix.isEmpty ? name : '$prefix/$name'; - - if (globs.any((g) => g.matches(path))) { - print( - 'Rendering Mustache template from ${entity.absolute.path} to ${targetFile.absolute.path}...'); - var contents = await entity.readAsString(); - var renderer = mustache.compile(contents); - var generated = renderer(values); - await targetFile.writeAsString(generated.toString()); - } else { - print( - 'Copying ${entity.absolute.path} to ${targetFile.absolute.path}...'); - await targetFile.parent.create(recursive: true); - await entity.copy(targetFile.absolute.path); - } - } catch (_) { - print('Failed to copy.'); - } - } else { - print('Skipped ${entity.absolute.path}.'); - } - } - } - } - - await merge(Directory.fromUri(packageDir.uri.resolve('files')), - Directory.current, ''); - print('Successfully installed $packageName@${projectPubspec.version}.'); - } - } else { - print('No add-ons were specified to be installed.'); - } - } - - Future> list() async { - if (!await installRepo.exists()) { - throw 'No local add-on database exists. Run `angel install --update` first.'; - } else { - List repos = []; - - await for (var entity in installRepo.list()) { - if (entity is Directory) { - try { - repos.add(await loadPubspec(entity)); - } catch (_) { - // Ignore failures... - } - } - } - - return repos; - } - } - - Future update() async { - Process git; - - if (!await installRepo.exists()) { - git = await Process.start('git', [ - 'clone', - repo, - installRepo.absolute.path, - ]); - } else { - git = await Process.start( - 'git', - [ - 'pull', - 'origin', - 'master', - ], - workingDirectory: installRepo.absolute.path, - ); - } - - git..stdout.listen(stdout.add)..stderr.listen(stderr.add); - - var code = await git.exitCode; - - if (code != 0) { - throw 'git exited with code $code.'; - } - } -} diff --git a/packages/cli/lib/src/commands/key.dart b/packages/cli/lib/src/commands/key.dart deleted file mode 100644 index 92e10456..00000000 --- a/packages/cli/lib/src/commands/key.dart +++ /dev/null @@ -1,30 +0,0 @@ -import 'dart:io'; -import 'package:args/command_runner.dart'; -import '../random_string.dart' as rs; - -class KeyCommand extends Command { - @override - String get name => 'key'; - - @override - String get description => 'Generates a new `angel_auth` key.'; - - @override - run() async { - var secret = rs.randomAlphaNumeric(32); - print('Generated new development JWT secret: $secret'); - await changeSecret(File('config/default.yaml'), secret); - - secret = rs.randomAlphaNumeric(32); - print('Generated new production JWT secret: $secret'); - await changeSecret(File('config/production.yaml'), secret); - } - - changeSecret(File file, String secret) async { - if (await file.exists()) { - var contents = await file.readAsString(); - contents = contents.replaceAll(RegExp(r'jwt_secret:[^\n]+\n?'), ''); - await file.writeAsString(contents.trim() + '\njwt_secret: "$secret"'); - } - } -} diff --git a/packages/cli/lib/src/commands/make.dart b/packages/cli/lib/src/commands/make.dart deleted file mode 100644 index 012cb9f9..00000000 --- a/packages/cli/lib/src/commands/make.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'package:args/command_runner.dart'; -import 'make/controller.dart'; -import 'make/migration.dart'; -import 'make/model.dart'; -import 'make/plugin.dart'; -import 'make/service.dart'; -import 'make/test.dart'; - -class MakeCommand extends Command { - @override - String get name => 'make'; - - @override - String get description => - 'Generates common code for your project, such as projects and controllers.'; - - MakeCommand() { - addSubcommand(ControllerCommand()); - addSubcommand(MigrationCommand()); - addSubcommand(ModelCommand()); - addSubcommand(PluginCommand()); - addSubcommand(TestCommand()); - addSubcommand(ServiceCommand()); - } -} diff --git a/packages/cli/lib/src/commands/make/controller.dart b/packages/cli/lib/src/commands/make/controller.dart deleted file mode 100644 index 1d51db01..00000000 --- a/packages/cli/lib/src/commands/make/controller.dart +++ /dev/null @@ -1,123 +0,0 @@ -import 'dart:io'; -import 'package:args/command_runner.dart'; -import 'package:code_builder/code_builder.dart'; -import 'package:dart_style/dart_style.dart'; -import 'package:io/ansi.dart'; -import 'package:prompts/prompts.dart' as prompts; -import 'package:recase/recase.dart'; -import '../../util.dart'; -import 'maker.dart'; - -class ControllerCommand extends Command { - @override - String get name => 'controller'; - - @override - String get description => 'Generates a controller class.'; - - ControllerCommand() { - argParser - ..addFlag('websocket', - abbr: 'w', - help: - 'Generates a WebSocketController, instead of an HTTP controller.', - negatable: false) - ..addOption('name', - abbr: 'n', help: 'Specifies a name for the model class.') - ..addOption('output-dir', - help: 'Specifies a directory to create the controller class in.', - defaultsTo: 'lib/src/routes/controllers'); - } - - @override - run() async { - var pubspec = await loadPubspec(); - String name; - if (argResults.wasParsed('name')) name = argResults['name'] as String; - - if (name?.isNotEmpty != true) { - name = prompts.get('Name of controller class'); - } - - List deps = [ - const MakerDependency('angel_framework', '^2.0.0') - ]; - - //${pubspec.name}.src.models.${rc.snakeCase} - - var rc = new ReCase(name); - var controllerLib = new Library((controllerLib) { - if (argResults['websocket'] as bool) { - deps.add(const MakerDependency('angel_websocket', '^2.0.0')); - controllerLib.directives - .add(new Directive.import('package:angel_websocket/server.dart')); - } else { - controllerLib.directives.add(new Directive.import( - 'package:angel_framework/angel_framework.dart')); - } - - controllerLib.body.add(new Class((clazz) { - clazz - ..name = '${rc.pascalCase}Controller' - ..extend = refer(argResults['websocket'] as bool - ? 'WebSocketController' - : 'Controller'); - - if (argResults['websocket'] as bool) { - // XController(AngelWebSocket ws) : super(ws); - clazz.constructors.add(new Constructor((b) { - b - ..requiredParameters.add(new Parameter((b) => b - ..name = 'ws' - ..type = refer('AngelWebSocket'))) - ..initializers.add(new Code('super(ws)')); - })); - - clazz.methods.add(new Method((meth) { - meth - ..name = 'hello' - ..returns = refer('void') - ..annotations - .add(refer('ExposeWs').call([literal('get_${rc.snakeCase}')])) - ..requiredParameters.add(new Parameter((b) => b - ..name = 'socket' - ..type = refer('WebSocketContext'))) - ..body = new Block((block) { - block.addExpression(refer('socket').property('send').call([ - literal('got_${rc.snakeCase}'), - literalMap({'message': literal('Hello, world!')}), - ])); - }); - })); - } else { - clazz - ..annotations - .add(refer('Expose').call([literal('/${rc.snakeCase}')])) - ..methods.add(new Method((meth) { - meth - ..name = 'hello' - ..returns = refer('String') - ..body = literal('Hello, world').returned.statement - ..annotations.add(refer('Expose').call([ - literal('/'), - ])); - })); - } - })); - }); - - var outputDir = new Directory.fromUri( - Directory.current.uri.resolve(argResults['output-dir'] as String)); - var controllerFile = - new File.fromUri(outputDir.uri.resolve('${rc.snakeCase}.dart')); - if (!await controllerFile.exists()) - await controllerFile.create(recursive: true); - await controllerFile.writeAsString(new DartFormatter() - .format(controllerLib.accept(new DartEmitter()).toString())); - - print(green.wrap( - '$checkmark Created controller file "${controllerFile.absolute.path}"')); - - if (deps.isNotEmpty) await depend(deps); - } -} diff --git a/packages/cli/lib/src/commands/make/maker.dart b/packages/cli/lib/src/commands/make/maker.dart deleted file mode 100644 index 09bf1bd9..00000000 --- a/packages/cli/lib/src/commands/make/maker.dart +++ /dev/null @@ -1,82 +0,0 @@ -import 'dart:async'; -import 'package:io/ansi.dart'; -import '../../util.dart'; - -class MakerDependency implements Comparable { - final String name, version; - final bool dev; - - const MakerDependency(this.name, this.version, {this.dev: false}); - - @override - int compareTo(MakerDependency other) => name.compareTo(other.name); -} - -Future depend(Iterable deps) async { - var pubspec = await loadPubspec(); - var missing = []; - - for (var dep in deps) { - var isPresent = false; - if (dep.dev) - isPresent = pubspec.devDependencies.containsKey(dep.name); - else - isPresent = pubspec.dependencies.containsKey(dep.name); - - if (!isPresent) { - missing.add(dep); -// TODO: https://github.com/dart-lang/pubspec_parse/issues/17: -// print('Installing ${dep.name}@${dep.version}...'); -// -// if (dep.dev) { -// pubspec.devDependencies[dep.name] = new HostedDependency( -// version: new VersionConstraint.parse(dep.version), -// ); -// } else { -// pubspec.dependencies[dep.name] = new HostedDependency( -// version: new VersionConstraint.parse(dep.version), -// ); -// } - } - } - - var missingDeps = missing.where((d) => !d.dev).toList()..sort(); - var missingDevDeps = missing.where((d) => d.dev).toList()..sort(); - var totalCount = missingDeps.length + missingDevDeps.length; - - if (totalCount > 0) { - print(yellow.wrap(totalCount == 1 - ? 'You are missing one dependency.' - : 'You are missing $totalCount dependencies.')); - print(yellow.wrap( - 'Update your `pubspec.yaml` to add the following dependencies:\n')); - - void printMissing(String type, Iterable deps) { - if (deps.isNotEmpty) { - print(yellow.wrap(' $type:')); - for (var dep in deps) { - print(yellow.wrap(' ${dep.name}: ${dep.version}')); - } - } - } - - printMissing('dependencies', missingDeps); - printMissing('dev_dependencies', missingDevDeps); - print('\n'); - } - -// if (isPresent) { -// TODO: https://github.com/dart-lang/pubspec_parse/issues/17 -// await savePubspec(pubspec); -// var pubPath = resolvePub(); -// -// print('Now running `$pubPath get`...'); -// -// var pubGet = await Process.start(pubPath, ['get']); -// pubGet.stdout.listen(stdout.add); -// pubGet.stderr.listen(stderr.add); -// -// var code = await pubGet.exitCode; -// -// if (code != 0) throw 'pub get terminated with exit code $code'; -} diff --git a/packages/cli/lib/src/commands/make/migration.dart b/packages/cli/lib/src/commands/make/migration.dart deleted file mode 100644 index a5792b0c..00000000 --- a/packages/cli/lib/src/commands/make/migration.dart +++ /dev/null @@ -1,133 +0,0 @@ -import 'dart:async'; -import 'dart:io'; -import 'package:args/command_runner.dart'; -import 'package:code_builder/code_builder.dart'; -import 'package:dart_style/dart_style.dart'; -import 'package:inflection2/inflection2.dart'; -import 'package:io/ansi.dart'; -import 'package:prompts/prompts.dart' as prompts; -import 'package:recase/recase.dart'; -import '../../util.dart'; -import 'maker.dart'; - -class MigrationCommand extends Command { - @override - String get name => 'migration'; - - @override - String get description => 'Generates a migration class.'; - - MigrationCommand() { - argParser - ..addOption('name', - abbr: 'n', help: 'Specifies a name for the model class.') - ..addOption('output-dir', - help: 'Specifies a directory to create the migration class in.', - defaultsTo: 'tool/migrations'); - } - - @override - FutureOr run() async { - String name; - if (argResults.wasParsed('name')) name = argResults['name'] as String; - - if (name?.isNotEmpty != true) { - name = prompts.get('Name of model class'); - } - - var deps = [const MakerDependency('angel_migration', '^2.0.0')]; - var rc = new ReCase(name); - - var migrationLib = new Library((migrationLib) { - migrationLib - ..directives.add(new Directive.import( - 'package:angel_migration.dart/angel_migration.dart')) - ..body.add(new Class((migrationClazz) { - migrationClazz - ..name = '${rc.pascalCase}Migration' - ..extend = refer('Migration'); - - var tableName = pluralize(rc.snakeCase); - - // up() - migrationClazz.methods.add(new Method((up) { - up - ..name = 'up' - ..returns = refer('void') - ..annotations.add(refer('override')) - ..requiredParameters.add(new Parameter((b) => b - ..name = 'schema' - ..type = refer('Schema'))) - ..body = new Block((block) { - // (table) { ... } - var callback = new Method((callback) { - callback - ..requiredParameters - .add(new Parameter((b) => b..name = 'table')) - ..body = new Block((block) { - var table = refer('table'); - - block.addExpression( - (table.property('serial').call([literal('id')])) - .property('primaryKey') - .call([]), - ); - - block.addExpression( - table.property('date').call([ - literal('created_at'), - ]), - ); - - block.addExpression( - table.property('date').call([ - literal('updated_at'), - ]), - ); - }); - }); - - block.addExpression(refer('schema').property('create').call([ - literal(tableName), - callback.closure, - ])); - }); - })); - - // down() - migrationClazz.methods.add(new Method((down) { - down - ..name = 'down' - ..returns = refer('void') - ..annotations.add(refer('override')) - ..requiredParameters.add(new Parameter((b) => b - ..name = 'schema' - ..type = refer('Schema'))) - ..body = new Block((block) { - block.addExpression( - refer('schema').property('drop').call([ - literal(tableName), - ]), - ); - }); - })); - })); - }); - - // Save migration file - var migrationDir = new Directory.fromUri( - Directory.current.uri.resolve(argResults['output-dir'] as String)); - var migrationFile = - new File.fromUri(migrationDir.uri.resolve('${rc.snakeCase}.dart')); - if (!await migrationFile.exists()) - await migrationFile.create(recursive: true); - - await migrationFile.writeAsString(new DartFormatter() - .format(migrationLib.accept(new DartEmitter()).toString())); - - print(green.wrap( - '$checkmark Created migration file "${migrationFile.absolute.path}".')); - - await depend(deps); - } -} diff --git a/packages/cli/lib/src/commands/make/model.dart b/packages/cli/lib/src/commands/make/model.dart deleted file mode 100644 index 04e964c8..00000000 --- a/packages/cli/lib/src/commands/make/model.dart +++ /dev/null @@ -1,122 +0,0 @@ -import 'dart:io'; -import 'package:args/command_runner.dart'; -import 'package:code_builder/code_builder.dart'; -import 'package:dart_style/dart_style.dart'; -import 'package:io/ansi.dart'; -import 'package:prompts/prompts.dart' as prompts; -import 'package:recase/recase.dart'; -import '../../util.dart'; -import 'maker.dart'; - -class ModelCommand extends Command { - @override - String get name => 'model'; - - @override - String get description => 'Generates a model class.'; - - ModelCommand() { - argParser - ..addFlag('migration', - abbr: 'm', - help: 'Generate migrations when running `build_runner`.', - defaultsTo: true) - ..addFlag('orm', help: 'Generate angel_orm code.', negatable: false) - ..addFlag('serializable', - help: 'Generate angel_serialize annotations.', defaultsTo: true) - ..addOption('name', - abbr: 'n', help: 'Specifies a name for the model class.') - ..addOption('output-dir', - help: 'Specifies a directory to create the model class in.', - defaultsTo: 'lib/src/models'); - } - - @override - run() async { - String name; - if (argResults.wasParsed('name')) name = argResults['name'] as String; - - if (name?.isNotEmpty != true) { - name = prompts.get('Name of model class'); - } - - List deps = [ - const MakerDependency('angel_model', '^1.0.0'), - ]; - - var rc = new ReCase(name); - - var modelLib = new Library((modelLib) { - if (argResults['orm'] as bool && argResults['migration'] as bool) { - modelLib.directives.addAll([ - new Directive.import('package:angel_migration/angel_migration.dart'), - ]); - } - - var needsSerialize = - argResults['serializable'] as bool || argResults['orm'] as bool; - // argResults['migration'] as bool; - - if (needsSerialize) { - modelLib.directives.add(new Directive.import( - 'package:angel_serialize/angel_serialize.dart')); - deps.add(const MakerDependency('angel_serialize', '^2.0.0')); - deps.add(const MakerDependency('angel_serialize_generator', '^2.0.0')); - deps.add(const MakerDependency('build_runner', '^1.0.0')); - } - - // else { - // modelLib.directives - // .add(new Directive.import('package:angel_model/angel_model.dart')); - // deps.add(const MakerDependency('angel_model', '^1.0.0')); - // } - - if (argResults['orm'] as bool) { - modelLib.directives.addAll([ - new Directive.import('package:angel_orm/angel_orm.dart'), - ]); - deps.add(const MakerDependency('angel_orm', '^2.0.0')); - } - - modelLib.body.addAll([ - new Code("part '${rc.snakeCase}.g.dart';"), - ]); - - modelLib.body.add(new Class((modelClazz) { - modelClazz - ..abstract = true - ..name = needsSerialize ? '_${rc.pascalCase}' : rc.pascalCase - ..extend = refer('Model'); - - if (needsSerialize) { - // modelLib.addDirective(new PartBuilder('${rc.snakeCase}.g.dart')); - modelClazz.annotations.add(refer('serializable')); - } - - if (argResults['orm'] as bool) { - if (argResults['migration'] as bool) { - modelClazz.annotations.add(refer('orm')); - } else { - modelClazz.annotations.add( - refer('Orm').call([], {'generateMigration': literalFalse})); - } - } - })); - }); - - // Save model file - var outputDir = new Directory.fromUri( - Directory.current.uri.resolve(argResults['output-dir'] as String)); - var modelFile = - new File.fromUri(outputDir.uri.resolve('${rc.snakeCase}.dart')); - if (!await modelFile.exists()) await modelFile.create(recursive: true); - - await modelFile.writeAsString(new DartFormatter() - .format(modelLib.accept(new DartEmitter()).toString())); - - print(green - .wrap('$checkmark Created model file "${modelFile.absolute.path}".')); - - if (deps.isNotEmpty) await depend(deps); - } -} diff --git a/packages/cli/lib/src/commands/make/plugin.dart b/packages/cli/lib/src/commands/make/plugin.dart deleted file mode 100644 index 4f979777..00000000 --- a/packages/cli/lib/src/commands/make/plugin.dart +++ /dev/null @@ -1,69 +0,0 @@ -import 'dart:io'; -import 'package:args/command_runner.dart'; -import 'package:dart_style/dart_style.dart'; -import 'package:io/ansi.dart'; -import 'package:prompts/prompts.dart' as prompts; -import 'package:pubspec_parse/pubspec_parse.dart'; -import 'package:recase/recase.dart'; -import '../../util.dart'; -import 'maker.dart'; - -class PluginCommand extends Command { - @override - String get name => "plugin"; - - @override - String get description => "Creates a new plug-in within the given project."; - - PluginCommand() { - argParser - ..addOption('name', - abbr: 'n', help: 'Specifies a name for the plug-in class.') - ..addOption('output-dir', - help: 'Specifies a directory to create the plug-in class in.', - defaultsTo: 'lib/src/config/plugins'); - } - - @override - run() async { - var pubspec = await loadPubspec(); - String name; - if (argResults.wasParsed('name')) name = argResults['name'] as String; - - if (name?.isNotEmpty != true) { - name = prompts.get('Name of plug-in class'); - } - - List deps = [ - const MakerDependency('angel_framework', '^2.0.0') - ]; - - var rc = new ReCase(name); - final pluginDir = new Directory.fromUri( - Directory.current.uri.resolve(argResults['output-dir'] as String)); - final pluginFile = - new File.fromUri(pluginDir.uri.resolve("${rc.snakeCase}.dart")); - if (!await pluginFile.exists()) await pluginFile.create(recursive: true); - await pluginFile.writeAsString( - new DartFormatter().format(_generatePlugin(pubspec, rc))); - - if (deps.isNotEmpty) await depend(deps); - - print(green.wrap( - '$checkmark Successfully generated plug-in file "${pluginFile.absolute.path}".')); - } - - String _generatePlugin(Pubspec pubspec, ReCase rc) { - return ''' -library ${pubspec.name}.src.config.plugins.${rc.snakeCase}; - -import 'package:angel_framework/angel_framework.dart'; - -AngelConfigurer ${rc.camelCase}() { - return (Angel app) async { - // Work some magic... - }; -} - '''; - } -} diff --git a/packages/cli/lib/src/commands/make/service.dart b/packages/cli/lib/src/commands/make/service.dart deleted file mode 100644 index a21d07f1..00000000 --- a/packages/cli/lib/src/commands/make/service.dart +++ /dev/null @@ -1,136 +0,0 @@ -import 'dart:io'; -import 'package:args/command_runner.dart'; -import 'package:code_builder/code_builder.dart'; -import 'package:dart_style/dart_style.dart'; -import 'package:inflection2/inflection2.dart'; -import 'package:io/ansi.dart'; -import 'package:prompts/prompts.dart' as prompts; -import 'package:pubspec_parse/pubspec_parse.dart'; -import 'package:recase/recase.dart'; -import '../service_generators/service_generators.dart'; -import '../../util.dart'; -import 'maker.dart'; - -class ServiceCommand extends Command { - @override - String get name => 'service'; - - @override - String get description => 'Generates an Angel service.'; - - ServiceCommand() { - argParser - ..addFlag('typed', - abbr: 't', - help: 'Wrap the generated service in a `TypedService` instance.', - negatable: false) - ..addOption('name', - abbr: 'n', help: 'Specifies a name for the service file.') - ..addOption('output-dir', - help: 'Specifies a directory to create the service file.', - defaultsTo: 'lib/src/services'); - } - - @override - run() async { - var pubspec = await loadPubspec(); - String name; - if (argResults.wasParsed('name')) name = argResults['name'] as String; - - if (name?.isNotEmpty != true) { - name = prompts.get('Name of service'); - } - - List deps = [ - const MakerDependency('angel_framework', '^2.0.0') - ]; - - // '${pubspec.name}.src.services.${rc.snakeCase}' - var rc = new ReCase(name); - var serviceLib = new Library((serviceLib) { - var generator = prompts.choose( - 'Choose which type of service to create', serviceGenerators); - -// if (generator == null) { -// _pen.red(); -// _pen('${Icon.BALLOT_X} \'$type\' services are not yet implemented. :('); -// _pen(); -// throw 'Unrecognized service type: "$type".'; -// } - - for (var dep in generator.dependencies) { - if (!deps.any((d) => d.name == dep.name)) deps.add(dep); - } - - if (generator.goesFirst) { - generator.applyToLibrary(serviceLib, name, rc.snakeCase); - serviceLib.directives.add(new Directive.import( - 'package:angel_framework/angel_framework.dart')); - } else { - serviceLib.directives.add(new Directive.import( - 'package:angel_framework/angel_framework.dart')); - generator.applyToLibrary(serviceLib, name, rc.snakeCase); - } - - if (argResults['typed'] as bool) { - serviceLib.directives - .add(new Directive.import('../models/${rc.snakeCase}.dart')); - } - - // configureServer() {} - serviceLib.body.add(new Method((configureServer) { - configureServer - ..name = 'configureServer' - ..returns = refer('AngelConfigurer'); - - configureServer.body = new Block((block) { - generator.applyToConfigureServer( - serviceLib, configureServer, block, name, rc.snakeCase); - - // return (Angel app) async {} - var closure = new Method((closure) { - closure - ..modifier = MethodModifier.async - ..requiredParameters.add(new Parameter((b) => b - ..name = 'app' - ..type = refer('Angel'))); - closure.body = new Block((block) { - generator.beforeService(serviceLib, block, name, rc.snakeCase); - - // app.use('/api/todos', new MapService()); - var service = generator.createInstance( - serviceLib, closure, name, rc.snakeCase); - - if (argResults['typed'] as bool) { - var tb = new TypeReference((b) => b - ..symbol = 'TypedService' - ..types.add(refer(rc.pascalCase))); - service = tb.newInstance([service]); - } - - block.addExpression(refer('app').property('use').call([ - literal('/api/${pluralize(rc.snakeCase)}'), - service, - ])); - }); - }); - - block.addExpression(closure.closure.returned); - }); - })); - }); - - final outputDir = new Directory.fromUri( - Directory.current.uri.resolve(argResults['output-dir'] as String)); - final serviceFile = - new File.fromUri(outputDir.uri.resolve("${rc.snakeCase}.dart")); - if (!await serviceFile.exists()) await serviceFile.create(recursive: true); - await serviceFile.writeAsString(new DartFormatter() - .format(serviceLib.accept(new DartEmitter()).toString())); - - print(green.wrap( - '$checkmark Successfully generated service file "${serviceFile.absolute.path}".')); - - if (deps.isNotEmpty) await depend(deps); - } -} diff --git a/packages/cli/lib/src/commands/make/test.dart b/packages/cli/lib/src/commands/make/test.dart deleted file mode 100644 index 32adcd7f..00000000 --- a/packages/cli/lib/src/commands/make/test.dart +++ /dev/null @@ -1,110 +0,0 @@ -import 'dart:io'; -import 'package:args/command_runner.dart'; -import 'package:dart_style/dart_style.dart'; -import 'package:io/ansi.dart'; -import 'package:prompts/prompts.dart' as prompter; -import 'package:pubspec_parse/pubspec_parse.dart'; -import 'package:recase/recase.dart'; -import '../../util.dart'; -import 'maker.dart'; - -class TestCommand extends Command { - @override - String get name => "test"; - - @override - String get description => "Creates a new test within the given project."; - - TestCommand() { - argParser - ..addFlag('run-configuration', - help: 'Generate a run configuration for JetBrains IDE\'s.', - defaultsTo: true) - ..addOption('name', - abbr: 'n', help: 'Specifies a name for the plug-in class.') - ..addOption('output-dir', - help: 'Specifies a directory to create the plug-in class in.', - defaultsTo: 'test'); - } - - @override - run() async { - var pubspec = await loadPubspec(); - String name; - if (argResults.wasParsed('name')) name = argResults['name'] as String; - - if (name?.isNotEmpty != true) { - name = prompter.get('Name of test'); - } - - List deps = [ - const MakerDependency('angel_framework', '^2.0.0'), - const MakerDependency('angel_test', '^2.0.0', dev: true), - const MakerDependency('test', '^1.0.0', dev: true), - ]; - - var rc = new ReCase(name); - final testDir = new Directory.fromUri( - Directory.current.uri.resolve(argResults['output-dir'] as String)); - final testFile = - new File.fromUri(testDir.uri.resolve("${rc.snakeCase}_test.dart")); - if (!await testFile.exists()) await testFile.create(recursive: true); - await testFile - .writeAsString(new DartFormatter().format(_generateTest(pubspec, rc))); - - if (deps.isNotEmpty) await depend(deps); - - print(green.wrap( - '$checkmark Successfully generated test file "${testFile.absolute.path}".')); - - if (argResults['run-configuration'] as bool) { - final runConfig = new File.fromUri(Directory.current.uri - .resolve('.idea/runConfigurations/${name}_Tests.xml')); - - if (!await runConfig.exists()) await runConfig.create(recursive: true); - await runConfig.writeAsString(_generateRunConfiguration(name, rc)); - - print(green.wrap( - '$checkmark Successfully generated run configuration "$name Tests" at "${runConfig.absolute.path}".')); - } - } - - String _generateRunConfiguration(String name, ReCase rc) { - return ''' - - - - -''' - .trim(); - } - - String _generateTest(Pubspec pubspec, ReCase rc) { - return ''' -import 'dart:io'; -import 'package:${pubspec.name}/${pubspec.name}.dart' as ${pubspec.name}; -import 'package:angel_framework/angel_framework.dart'; -import 'package:angel_test/angel_test.dart'; -import 'package:test/test.dart'; - -main() async { - TestClient client; - - setUp(() async { - var app = new Angel(); - await app.configure(${pubspec.name}.configureServer); - client = await connectTo(app); - }); - - tearDown(() => client.close()); - - test('${rc.snakeCase}', () async { - final response = await client.get('/${rc.snakeCase}'); - expect(response, hasStatus(HttpStatus.ok)); - }); -} - '''; - } -} diff --git a/packages/cli/lib/src/commands/pub.dart b/packages/cli/lib/src/commands/pub.dart deleted file mode 100644 index 1b582ebc..00000000 --- a/packages/cli/lib/src/commands/pub.dart +++ /dev/null @@ -1,12 +0,0 @@ -import 'dart:io'; - -final RegExp _leadingSlashes = RegExp(r'^/+'); - -String resolvePub() { - var exec = File(Platform.resolvedExecutable); - var pubPath = exec.parent.uri.resolve('pub').path; - if (Platform.isWindows) - pubPath = pubPath.replaceAll(_leadingSlashes, '') + '.bat'; - pubPath = Uri.decodeFull(pubPath); - return pubPath; -} diff --git a/packages/cli/lib/src/commands/rename.dart b/packages/cli/lib/src/commands/rename.dart deleted file mode 100644 index 49e5bd00..00000000 --- a/packages/cli/lib/src/commands/rename.dart +++ /dev/null @@ -1,194 +0,0 @@ -import 'dart:io'; -import 'package:analyzer/dart/ast/ast.dart'; -import 'package:analyzer/dart/ast/visitor.dart'; -import 'package:args/command_runner.dart'; -import 'package:dart_style/dart_style.dart'; -import 'package:glob/glob.dart'; -import 'package:glob/list_local_fs.dart'; -import 'package:io/ansi.dart'; -import 'package:prompts/prompts.dart' as prompts; -import 'package:recase/recase.dart'; -import '../util.dart'; -import 'pub.dart'; - -class RenameCommand extends Command { - @override - String get name => 'rename'; - - @override - String get description => 'Renames the current project (To be available).'; - - @override - String get invocation => '$name '; - - @override - run() async { - String newName; - - if (argResults.rest.isNotEmpty) - newName = argResults.rest.first; - else { - newName = prompts.get('Rename project to'); - } - - newName = ReCase(newName).snakeCase; - - var choice = prompts.getBool('Rename the project to `$newName`?'); - - // TODO: To be available once the issue is fixed - if (choice) { - print('Rename the project is currently not available'); - /* - print('Renaming project to `$newName`...'); - var pubspecFile = - File.fromUri(Directory.current.uri.resolve('pubspec.yaml')); - - if (!await pubspecFile.exists()) { - throw Exception('No pubspec.yaml found in current directory.'); - } else { - var pubspec = await loadPubspec(); - var oldName = pubspec.name; - await renamePubspec(Directory.current, oldName, newName); - await renameDartFiles(Directory.current, oldName, newName); - print('Now running `pub get`...'); - var pubPath = resolvePub(); - print('Pub path: $pubPath'); - var pub = await Process.start(pubPath, ['get']); - stdout.addStream(pub.stdout); - stderr.addStream(pub.stderr); - await pub.exitCode; - } - */ - } - } -} - -renamePubspec(Directory dir, String oldName, String newName) async { -// var pubspec = await loadPubspec(dir); - print(cyan.wrap('Renaming your project to `$newName.`')); - - var pubspecFile = File.fromUri(dir.uri.resolve('pubspec.yaml')); - - if (await pubspecFile.exists()) { - var contents = await pubspecFile.readAsString(), oldContents = contents; - contents = - contents.replaceAll(RegExp('name:\\s*$oldName'), 'name: $newName'); - - if (contents != oldContents) { - await pubspecFile.writeAsString(contents); - } - } - -// print(cyan -// .wrap('Note that this does not actually modify your `pubspec.yaml`.')); -// TODO: https://github.com/dart-lang/pubspec_parse/issues/17 -// var newPubspec = Pubspec.fromJson(pubspec.toJson()..['name'] = newName); -// await newPubspec.save(dir); -} - -renameDartFiles(Directory dir, String oldName, String newName) async { - if (!await dir.exists()) return; - - // Try to replace MongoDB URL - var configGlob = Glob('config/**/*.yaml'); - - try { - await for (var yamlFile in configGlob.list(root: dir.absolute.path)) { - if (yamlFile is File) { - print( - 'Replacing occurrences of "$oldName" with "$newName" in file "${yamlFile.absolute.path}"...'); - if (yamlFile is File) { - var contents = (yamlFile as File).readAsStringSync(); - contents = contents.replaceAll(oldName, newName); - (yamlFile as File).writeAsStringSync(contents); - } - } - } - } catch (_) {} - - var entry = File.fromUri(dir.uri.resolve('lib/$oldName.dart')); - - if (await entry.exists()) { - await entry.rename(dir.uri.resolve('lib/$newName.dart').toFilePath()); - print('Renaming library file `${entry.absolute.path}`...'); - } - - var fmt = DartFormatter(); - await for (FileSystemEntity file in dir.list(recursive: true)) { - if (file is File && file.path.endsWith('.dart')) { - var contents = await file.readAsString(); - - // TODO: Issue to be fixed: parseCompilationUnit uses Hubbub library which uses discontinued Google front_end library - // front_end package. Temporarily commeted out - //var ast = parseCompilationUnit(contents); - var visitor = RenamingVisitor(oldName, newName); - // ..visitCompilationUnit(ast); - - if (visitor.replace.isNotEmpty) { - visitor.replace.forEach((range, replacement) { - if (range.first is int) { - contents = contents.replaceRange( - range.first as int, range.last as int, replacement); - } else if (range.first is String) { - contents = contents.replaceAll(range.first as String, replacement); - } - }); - - await file.writeAsString(fmt.format(contents)); - print('Updated file `${file.absolute.path}`.'); - } - } - } -} - -class RenamingVisitor extends RecursiveAstVisitor { - final String oldName, newName; - final Map replace = {}; - - RenamingVisitor(this.oldName, this.newName) { - replace[['{{$oldName}}']] = newName; - } - - String updateUri(String uri) { - if (uri == 'package:$oldName/$oldName.dart') { - return 'package:$newName/$newName.dart'; - } else if (uri.startsWith('package:$oldName/')) { - return 'package:$newName/' + uri.replaceFirst('package:$oldName/', ''); - } else - return uri; - } - - @override - visitExportDirective(ExportDirective ctx) { - var uri = ctx.uri.stringValue, updated = updateUri(uri); - if (uri != updated) replace[[uri]] = updated; - } - - @override - visitImportDirective(ImportDirective ctx) { - var uri = ctx.uri.stringValue, updated = updateUri(uri); - if (uri != updated) replace[[uri]] = updated; - } - - @override - visitLibraryDirective(LibraryDirective ctx) { - var name = ctx.name.name; - - if (name.startsWith(oldName)) { - replace[[ctx.offset, ctx.end]] = - 'library ' + name.replaceFirst(oldName, newName) + ';'; - } - } - - @override - visitPartOfDirective(PartOfDirective ctx) { - if (ctx.libraryName != null) { - var name = ctx.libraryName.name; - - if (name.startsWith(oldName)) { - replace[[ctx.offset, ctx.end]] = - 'part of ' + name.replaceFirst(oldName, newName) + ';'; - } - } - } -} diff --git a/packages/cli/lib/src/commands/service_generators/custom.dart b/packages/cli/lib/src/commands/service_generators/custom.dart deleted file mode 100644 index 9008b695..00000000 --- a/packages/cli/lib/src/commands/service_generators/custom.dart +++ /dev/null @@ -1,27 +0,0 @@ -import 'package:code_builder/code_builder.dart'; -import 'generator.dart'; - -class CustomServiceGenerator extends ServiceGenerator { - @override - bool get createsModel => false; - - @override - bool get createsValidator => false; - - const CustomServiceGenerator() : super('Custom'); - - @override - void applyToLibrary(LibraryBuilder library, String name, String lower) { - library.body.add(Class((clazz) { - clazz - ..name = '${name}Service' - ..extend = refer('Service'); - })); - } - - @override - Expression createInstance(LibraryBuilder library, MethodBuilder methodBuilder, - String name, String lower) { - return refer('${name}Service').newInstance([]); - } -} diff --git a/packages/cli/lib/src/commands/service_generators/file_service.dart b/packages/cli/lib/src/commands/service_generators/file_service.dart deleted file mode 100644 index 39e1086e..00000000 --- a/packages/cli/lib/src/commands/service_generators/file_service.dart +++ /dev/null @@ -1,48 +0,0 @@ -import 'generator.dart'; -import 'package:code_builder/code_builder.dart'; -import 'package:inflection2/inflection2.dart'; -import '../make/maker.dart'; - -class FileServiceGenerator extends ServiceGenerator { - const FileServiceGenerator() : super('Persistent JSON File'); - - @override - List get dependencies => - const [const MakerDependency('angel_file_service', '^2.0.0')]; - - @override - bool get goesFirst => true; - - @override - void applyToConfigureServer( - LibraryBuilder library, - MethodBuilder configureServer, - BlockBuilder block, - String name, - String lower) { - configureServer.requiredParameters.add(new Parameter((b) => b - ..name = 'dbDirectory' - ..type = refer('Directory'))); - } - - @override - void applyToLibrary(LibraryBuilder library, String name, String lower) { - library.directives.addAll([ - new Directive.import( - 'package:angel_file_service/angel_file_service.dart'), - ]); - } - - @override - Expression createInstance(LibraryBuilder library, MethodBuilder methodBuilder, - String name, String lower) { - library.directives.addAll([ - new Directive.import('package:file/file.dart'), - ]); - return refer('JsonFileService').newInstance([ - refer('dbDirectory') - .property('childFile') - .call([literal(pluralize(lower) + '_db.json')]) - ]); - } -} diff --git a/packages/cli/lib/src/commands/service_generators/generator.dart b/packages/cli/lib/src/commands/service_generators/generator.dart deleted file mode 100644 index 63289581..00000000 --- a/packages/cli/lib/src/commands/service_generators/generator.dart +++ /dev/null @@ -1,46 +0,0 @@ -import 'package:code_builder/code_builder.dart'; -import '../make/maker.dart'; - -class ServiceGenerator { - final String name; - - const ServiceGenerator(this.name); - - List get dependencies => []; - - @deprecated - bool get createsModel => true; - - @deprecated - bool get createsValidator => true; - - @deprecated - bool get exportedInServiceLibrary => true; - - @deprecated - bool get injectsSingleton => false; - - @deprecated - bool get shouldRunBuild => false; - - bool get goesFirst => false; - - void applyToLibrary(LibraryBuilder library, String name, String lower) {} - - void beforeService(LibraryBuilder library, BlockBuilder builder, String name, - String lower) {} - - void applyToConfigureServer( - LibraryBuilder library, - MethodBuilder configureServer, - BlockBuilder block, - String name, - String lower) {} - - Expression createInstance(LibraryBuilder library, MethodBuilder methodBuilder, - String name, String lower) => - literal(null); - - @override - String toString() => name; -} diff --git a/packages/cli/lib/src/commands/service_generators/map.dart b/packages/cli/lib/src/commands/service_generators/map.dart deleted file mode 100644 index 545961df..00000000 --- a/packages/cli/lib/src/commands/service_generators/map.dart +++ /dev/null @@ -1,15 +0,0 @@ -import 'generator.dart'; -import 'package:code_builder/code_builder.dart'; - -class MapServiceGenerator extends ServiceGenerator { - const MapServiceGenerator() : super('In-Memory'); - - @override - bool get createsModel => false; - - @override - Expression createInstance(LibraryBuilder library, MethodBuilder methodBuilder, - String name, String lower) { - return refer('MapService').newInstance([]); - } -} diff --git a/packages/cli/lib/src/commands/service_generators/mongo.dart b/packages/cli/lib/src/commands/service_generators/mongo.dart deleted file mode 100644 index d8d2f0d3..00000000 --- a/packages/cli/lib/src/commands/service_generators/mongo.dart +++ /dev/null @@ -1,43 +0,0 @@ -import 'generator.dart'; -import 'package:code_builder/code_builder.dart'; -import 'package:inflection2/inflection2.dart'; -import '../make/maker.dart'; - -class MongoServiceGenerator extends ServiceGenerator { - const MongoServiceGenerator() : super('MongoDB'); - - @override - List get dependencies => - const [const MakerDependency('angel_mongo', '^2.0.0')]; - - @override - bool get createsModel => false; - - @override - void applyToConfigureServer( - LibraryBuilder library, - MethodBuilder configureServer, - BlockBuilder block, - String name, - String lower) { - configureServer.requiredParameters.add(new Parameter((b) => b - ..name = 'db' - ..type = refer('Db'))); - } - - @override - void applyToLibrary(LibraryBuilder library, String name, String lower) { - library.directives.addAll([ - new Directive.import('package:angel_mongo/angel_mongo.dart'), - new Directive.import('package:mongo_dart/mongo_dart.dart'), - ]); - } - - @override - Expression createInstance(LibraryBuilder library, MethodBuilder methodBuilder, - String name, String lower) { - return refer('MongoService').newInstance([ - refer('db').property('collection').call([literal(pluralize(lower))]) - ]); - } -} diff --git a/packages/cli/lib/src/commands/service_generators/rethink.dart b/packages/cli/lib/src/commands/service_generators/rethink.dart deleted file mode 100644 index 49cc78c1..00000000 --- a/packages/cli/lib/src/commands/service_generators/rethink.dart +++ /dev/null @@ -1,49 +0,0 @@ -import 'generator.dart'; -import 'package:code_builder/code_builder.dart'; -import 'package:inflection2/inflection2.dart'; -import '../make/maker.dart'; - -class RethinkServiceGenerator extends ServiceGenerator { - const RethinkServiceGenerator() : super('RethinkDB'); - - @override - List get dependencies => - const [const MakerDependency('angel_rethink', '^2.0.0')]; - - @override - bool get createsModel => false; - - @override - void applyToConfigureServer( - LibraryBuilder library, - MethodBuilder configureServer, - BlockBuilder block, - String name, - String lower) { - configureServer.requiredParameters.addAll([ - new Parameter((b) => b - ..name = 'connection' - ..type = refer('Connection')), - new Parameter((b) => b - ..name = 'r' - ..type = refer('Rethinkdb')), - ]); - } - - @override - void applyToLibrary(LibraryBuilder library, String name, String lower) { - library.directives.addAll([ - 'package:angel_rethink/angel_rethink.dart', - 'package:rethinkdb_dart/rethinkdb_dart.dart' - ].map((str) => new Directive.import(str))); - } - - @override - Expression createInstance(LibraryBuilder library, MethodBuilder methodBuilder, - String name, String lower) { - return refer('RethinkService').newInstance([ - refer('connection'), - refer('r').property('table').call([literal(pluralize(lower))]) - ]); - } -} diff --git a/packages/cli/lib/src/commands/service_generators/service_generators.dart b/packages/cli/lib/src/commands/service_generators/service_generators.dart deleted file mode 100644 index 813adc18..00000000 --- a/packages/cli/lib/src/commands/service_generators/service_generators.dart +++ /dev/null @@ -1,15 +0,0 @@ -import 'custom.dart'; -import 'file_service.dart'; -import 'generator.dart'; -import 'map.dart'; -import 'mongo.dart'; -import 'rethink.dart'; -export 'generator.dart'; - -const List serviceGenerators = const [ - const MapServiceGenerator(), - const FileServiceGenerator(), - const MongoServiceGenerator(), - const RethinkServiceGenerator(), - const CustomServiceGenerator() -]; diff --git a/packages/cli/lib/src/random_string.dart b/packages/cli/lib/src/random_string.dart deleted file mode 100644 index 9f539aaf..00000000 --- a/packages/cli/lib/src/random_string.dart +++ /dev/null @@ -1,15 +0,0 @@ -import 'dart:math'; - -const String _valid = - 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; -final Random _rnd = Random.secure(); - -String randomAlphaNumeric(int length) { - var b = StringBuffer(); - - for (int i = 0; i < length; i++) { - b.writeCharCode(_valid.codeUnitAt(_rnd.nextInt(_valid.length))); - } - - return b.toString(); -} diff --git a/packages/cli/lib/src/util.dart b/packages/cli/lib/src/util.dart deleted file mode 100644 index a294d40c..00000000 --- a/packages/cli/lib/src/util.dart +++ /dev/null @@ -1,77 +0,0 @@ -import 'dart:async'; -import 'dart:io'; -import 'package:io/ansi.dart'; -import 'package:path/path.dart' as p; -import 'package:pubspec_parse/pubspec_parse.dart'; -//import 'package:yamlicious/yamlicious.dart'; - -final String checkmark = ansiOutputEnabled ? '\u2714' : '[Success]'; - -final String ballot = ansiOutputEnabled ? '\u2717' : '[Failure]'; - -String get homeDirPath => - Platform.environment['HOME'] ?? Platform.environment['USERPROFILE']; - -Directory get homeDir => new Directory(homeDirPath); - -Directory get angelDir => Directory(p.join(homeDir.path, '.angel')); - -Future loadPubspec([Directory directory]) { - directory ??= Directory.current; - var file = new File.fromUri(directory.uri.resolve('pubspec.yaml')); - return file - .readAsString() - .then((yaml) => new Pubspec.parse(yaml, sourceUrl: file.uri)); -} - -// From: https://gist.github.com/tobischw/98dcd2563eec9a2a87bda8299055358a -Future copyDirectory(Directory source, Directory destination) async { - // if (!topLevel) stdout.write('\r'); - // print(darkGray - // .wrap('Copying dir "${source.path}" -> "${destination.path}..."')); - - await for (var entity in source.list(recursive: false)) { - if (p.basename(entity.path) == '.git') continue; - if (entity is Directory) { - var newDirectory = - Directory(p.join(destination.absolute.path, p.basename(entity.path))); - await newDirectory.create(recursive: true); - await copyDirectory(entity.absolute, newDirectory); - } else if (entity is File) { - var newPath = p.join(destination.path, p.basename(entity.path)); - // print(darkGray.wrap('\rCopying file "${entity.path}" -> "$newPath"')); - await File(newPath).create(recursive: true); - await entity.copy(newPath); - } - } - - // print('\rCopied "${source.path}" -> "${destination.path}.'); -} - -Future savePubspec(Pubspec pubspec) async { - // TODO: Save pubspec for real? - //var text = toYamlString(pubspec); -} - -Future runCommand(String exec, List args) async { - var s = '$exec ${args.join(' ')}'.trim(); - stdout.write(darkGray.wrap('Running `$s`... ')); - - try { - var p = await Process.start(exec, args); - var code = await p.exitCode; - - if (code == 0) { - print(green.wrap(checkmark)); - return true; - } else { - print(red.wrap(ballot)); - await stdout.addStream(p.stdout); - await stderr.addStream(p.stderr); - return false; - } - } catch (e) { - print(red.wrap('$ballot Failed to run process.')); - return false; - } -} diff --git a/packages/cli/pubspec.yaml b/packages/cli/pubspec.yaml deleted file mode 100644 index d8d35e6c..00000000 --- a/packages/cli/pubspec.yaml +++ /dev/null @@ -1,27 +0,0 @@ -#author: Tobe O -description: Command-line tools for the Angel framework, including scaffolding. -homepage: https://github.com/dukefirehawk/angel/packages/angel_cli -name: angel_cli -version: 3.0.0 -environment: - sdk: ">=2.10.0 <3.0.0" -dependencies: - analyzer: ^1.1.0 - args: ^2.0.0 - code_builder: ^3.0.0 - dart_style: ^1.0.0 - glob: ^2.0.0 - http: ^0.13.0 - io: ^0.3.5 - inflection2: ^0.4.2 - mustache4dart2: ^0.1.0 - path: ^1.0.0 - prompts: ^1.3.1 - pubspec_parse: ^1.0.0 - quiver: ^3.0.0 - recase: ^3.0.1 - shutdown: ^0.4.0 - watcher: ^1.0.0 - yaml: ^3.0.0 -executables: - angel: angel diff --git a/packages/cli/screenshots/screenshot.png b/packages/cli/screenshots/screenshot.png deleted file mode 100644 index fe8c9652e90163723a8df8bbba0757f07f1e244d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 84903 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 tcFC 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 - - - - - - - - - - - - - \ No newline at end of file diff --git a/packages/graphql/.idea/modules.xml b/packages/graphql/.idea/modules.xml deleted file mode 100644 index 08c6fba9..00000000 --- a/packages/graphql/.idea/modules.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/packages/graphql/.idea/runConfigurations/main_dart.xml b/packages/graphql/.idea/runConfigurations/main_dart.xml deleted file mode 100644 index 3df76abf..00000000 --- a/packages/graphql/.idea/runConfigurations/main_dart.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - \ No newline at end of file diff --git a/packages/graphql/.idea/runConfigurations/objects_in_equality_test_dart.xml b/packages/graphql/.idea/runConfigurations/objects_in_equality_test_dart.xml deleted file mode 100644 index 47dbf8c5..00000000 --- a/packages/graphql/.idea/runConfigurations/objects_in_equality_test_dart.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - \ No newline at end of file diff --git a/packages/graphql/.idea/runConfigurations/server_dart.xml b/packages/graphql/.idea/runConfigurations/server_dart.xml deleted file mode 100644 index 04395e78..00000000 --- a/packages/graphql/.idea/runConfigurations/server_dart.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - \ No newline at end of file diff --git a/packages/graphql/.idea/runConfigurations/tests_in_comment_test_dart.xml b/packages/graphql/.idea/runConfigurations/tests_in_comment_test_dart.xml deleted file mode 100644 index 29f7faf4..00000000 --- a/packages/graphql/.idea/runConfigurations/tests_in_comment_test_dart.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/packages/graphql/.idea/runConfigurations/tests_in_graphql_parser.xml b/packages/graphql/.idea/runConfigurations/tests_in_graphql_parser.xml deleted file mode 100644 index 854ed556..00000000 --- a/packages/graphql/.idea/runConfigurations/tests_in_graphql_parser.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - \ No newline at end of file diff --git a/packages/graphql/.idea/runConfigurations/tests_in_graphql_schema.xml b/packages/graphql/.idea/runConfigurations/tests_in_graphql_schema.xml deleted file mode 100644 index b3d4f5e6..00000000 --- a/packages/graphql/.idea/runConfigurations/tests_in_graphql_schema.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - \ No newline at end of file diff --git a/packages/graphql/.idea/runConfigurations/tests_in_mirrors_test_dart.xml b/packages/graphql/.idea/runConfigurations/tests_in_mirrors_test_dart.xml deleted file mode 100644 index c9450200..00000000 --- a/packages/graphql/.idea/runConfigurations/tests_in_mirrors_test_dart.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - \ No newline at end of file diff --git a/packages/graphql/.idea/runConfigurations/tests_in_query_test_dart.xml b/packages/graphql/.idea/runConfigurations/tests_in_query_test_dart.xml deleted file mode 100644 index 9ab72dfa..00000000 --- a/packages/graphql/.idea/runConfigurations/tests_in_query_test_dart.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - \ No newline at end of file diff --git a/packages/graphql/.idea/runConfigurations/tests_in_validation_test_dart.xml b/packages/graphql/.idea/runConfigurations/tests_in_validation_test_dart.xml deleted file mode 100644 index 863374eb..00000000 --- a/packages/graphql/.idea/runConfigurations/tests_in_validation_test_dart.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - \ No newline at end of file diff --git a/packages/graphql/.idea/runConfigurations/tests_in_value_test_dart.xml b/packages/graphql/.idea/runConfigurations/tests_in_value_test_dart.xml deleted file mode 100644 index 58aca4ef..00000000 --- a/packages/graphql/.idea/runConfigurations/tests_in_value_test_dart.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - \ No newline at end of file diff --git a/packages/graphql/.idea/vcs.xml b/packages/graphql/.idea/vcs.xml deleted file mode 100644 index 94a25f7f..00000000 --- a/packages/graphql/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/packages/graphql/.travis.yml b/packages/graphql/.travis.yml deleted file mode 100644 index 903bc5ea..00000000 --- a/packages/graphql/.travis.yml +++ /dev/null @@ -1,6 +0,0 @@ -language: dart -dart: - - dev - - stable -script: - - bash -ex travis.sh \ No newline at end of file diff --git a/packages/graphql/LICENSE b/packages/graphql/LICENSE deleted file mode 100644 index 89074fd3..00000000 --- a/packages/graphql/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2017 The Angel Framework - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/packages/graphql/README.md b/packages/graphql/README.md index a74491d1..2f4e55c7 100644 --- a/packages/graphql/README.md +++ b/packages/graphql/README.md @@ -1,39 +1,3 @@ -![Logo](https://github.com/angel-dart/graphql/raw/master/img/angel_logo.png) +# GraphQL -
-
-
Pub -Pub -
- - -A complete implementation of the official -[GraphQL specification](https://graphql.github.io/graphql-spec/June2018/), -in the Dart programming language. - -The goal of this project is to provide to server-side -users of Dart an alternative to REST API's. - -Included is also -`package:angel_graphql`, which, when combined with the -[Angel](https://github.com/angel-dart) framework, allows -server-side Dart users to build backends with GraphQL and -virtually any database imaginable. - -## Tutorial Demo (click to watch) -[![Youtube thumbnail](video.png)](https://youtu.be/5x6S4kDODa8) - -## Projects -This mono repo is split into several sub-projects, -each with its own detailed documentation and examples: -* `angel_graphql` - Support for handling GraphQL via HTTP and -WebSockets in the [Angel](https://angel-dart.dev) framework. Also serves as the `package:graphql_server` reference implementation. -* `data_loader` - A Dart port of [`graphql/data_loader`](https://github.com/graphql/dataloader). -* `example_star_wars`: An example GraphQL API built using -`package:angel_graphql`. -* `graphql_generator`: Generates `package:graphql_schema` object types from concrete Dart classes. -* `graphql_parser`: A recursive descent parser for the GraphQL language. -* `graphql_schema`: An implementation of GraphQL's type system. This, combined with `package:graphql_parser`, -powers `package:graphql_server`. -* `graphql_server`: Base functionality for implementing GraphQL servers in Dart. Has no dependency on any -framework. \ No newline at end of file +Moved to [`GraphQL Repo`](https://github.com/dukefirehawk/graphql_dart) \ No newline at end of file diff --git a/packages/graphql/angel_graphql/.gitignore b/packages/graphql/angel_graphql/.gitignore deleted file mode 100644 index 8b0bbf6d..00000000 --- a/packages/graphql/angel_graphql/.gitignore +++ /dev/null @@ -1,94 +0,0 @@ -# See https://www.dartlang.org/tools/private-files.html - -# Files and directories created by pub -.buildlog -.packages -.project -.pub/ -.scripts-bin/ -build/ -**/packages/ -posts.json - -# Files created by dart2js -# (Most Dart developers will use pub build to compile Dart, use/modify these -# rules if you intend to use dart2js directly -# Convention is to use extension '.dart.js' for Dart compiled to Javascript to -# differentiate from explicit Javascript files) -*.dart.js -*.part.js -*.js.deps -*.js.map -*.info.json - -# Directory created by dartdoc -doc/api/ - -# Don't commit pubspec lock file -# (Library packages only! Remove pattern if developing an application package) -pubspec.lock -### Dart template -# See https://www.dartlang.org/tools/private-files.html - -# Files and directories created by pub - -# SDK 1.20 and later (no longer creates packages directories) - -# Older SDK versions -# (Include if the minimum SDK version specified in pubsepc.yaml is earlier than 1.20) - - -# Files created by dart2js -# (Most Dart developers will use pub build to compile Dart, use/modify these -# rules if you intend to use dart2js directly -# Convention is to use extension '.dart.js' for Dart compiled to Javascript to -# differentiate from explicit Javascript files) - -# Directory created by dartdoc - -# Don't commit pubspec lock file -# (Library packages only! Remove pattern if developing an application package) -### JetBrains template -# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm -# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 - -# User-specific stuff: -../.idea/workspace.xml -.idea/**/tasks.xml -.idea/dictionaries - -# Sensitive or high-churn files: -.idea/**/dataSources/ -.idea/**/dataSources.ids -.idea/**/dataSources.xml -.idea/**/dataSources.local.xml -.idea/**/sqlDataSources.xml -.idea/**/dynamic.xml -.idea/**/uiDesigner.xml - -# Gradle: -.idea/**/gradle.xml -.idea/**/libraries - -# Mongo Explorer plugin: -.idea/**/mongoSettings.xml - -## File-based project format: -*.iws - -## Plugin-specific files: - -# IntelliJ -/out/ - -# mpeltonen/sbt-idea plugin -.idea_modules/ - -# JIRA plugin -atlassian-ide-plugin.xml - -# Crashlytics plugin (for Android Studio and IntelliJ) -com_crashlytics_export_strings.xml -crashlytics.properties -crashlytics-build.properties -fabric.properties diff --git a/packages/graphql/angel_graphql/CHANGELOG.md b/packages/graphql/angel_graphql/CHANGELOG.md deleted file mode 100644 index faaed134..00000000 --- a/packages/graphql/angel_graphql/CHANGELOG.md +++ /dev/null @@ -1,17 +0,0 @@ -# 1.1.0 -* Support the GraphQL multipart spec: https://github.com/jaydenseric/graphql-multipart-request-spec - -# 1.0.0 -* Apply `package:pedantic`. - -# 1.0.0-rc.0 -* Finish `graphQLWS`. - -# 1.0.0-beta.1 -* Add `graphQLWS` handler, and support subscriptions. - -# 1.0.0-beta -* Angel RC updates. - -# 1.0.0-alpha -* First official release. \ No newline at end of file diff --git a/packages/graphql/angel_graphql/LICENSE b/packages/graphql/angel_graphql/LICENSE deleted file mode 100644 index 89074fd3..00000000 --- a/packages/graphql/angel_graphql/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2017 The Angel Framework - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/packages/graphql/angel_graphql/README.md b/packages/graphql/angel_graphql/README.md deleted file mode 100644 index bbb1f67c..00000000 --- a/packages/graphql/angel_graphql/README.md +++ /dev/null @@ -1,297 +0,0 @@ -![Logo](https://github.com/angel-dart/graphql/raw/master/img/angel_logo.png) - -
-
-Pub -Pub -
- -* [Installation](#installation) -* [Usage](#usage) -* [Subscriptions](#subscriptions) -* [Integration with Angel `Service`s](#using-services) -* [Documenting API's](#documentation) -* [Deprecated - Mirrors Usage](#mirrors) - -A complete implementation of the official -[GraphQL specification](http://facebook.github.io/graphql/October2016/#sec-Language) - these -are the [Angel framework](https://angel-dart.github.io)-specific -bindings. - -The goal of this project is to provide to server-side -users of Dart an alternative to REST API's. `package:angel_graphql`, which, when combined with the allows -server-side Dart users to build backends with GraphQL and -virtually any database imaginable. - -## Installation -To install `package:angel_graphql`, add the following to your -`pubspec.yaml`: - -```yaml -dependencies: - angel_framework: ^2.0.0-alpha - angel_graphql: ^1.0.0-alpha -``` - -## Usage -Using this package is very similar to GraphQL.js - you define -a schema, and then mount `graphQLHttp` in your router to start -serving. This implementation supports GraphQL features like -introspection, so you can play around with `graphiql` as well! - -Firstly, define your schema. A GraphQL schema contains an -*object type* that defines all querying operations that can be -applied to the backend. - -A GraphQL schema may also have a *mutation* object type, -which defines operations that change the backend's state, and -optionally a *subscription* type, which defines real-time -interactions (coming soon!). - -You can use the `convertDartType` helper to wrap your existing -`Model`/PODO classes, and make GraphQL aware of them without duplicated -effort. - -```dart -import 'package:angel_framework/angel_framework.dart'; -import 'package:angel_graphql/angel_graphql.dart'; -import 'package:graphql_schema/graphql_schema.dart'; -import 'package:graphql_server/graphql_server.dart'; -import 'package:graphql_server/mirrors.dart'; - -Future configureServer(Angel app) async { - var queryType = objectType( - 'Query', - description: 'A simple API that manages your to-do list.', - fields: [ - field( - 'todos', - listOf(convertDartType(Todo).nonNullable()), - resolve: resolveViaServiceIndex(todoService), - ), - field( - 'todo', - convertDartType(Todo), - resolve: resolveViaServiceRead(todoService), - inputs: [ - GraphQLFieldInput('id', graphQLId.nonNullable()), - ], - ), - ], - ); - - var mutationType = objectType( - 'Mutation', - description: 'Modify the to-do list.', - fields: [ - field( - 'create', - graphQLString, - ), - ], - ); - - var schema = graphQLSchema( - queryType: queryType, - mutationType: mutationType, - ); -} -``` - -After you've created your `GraphQLSchema`, you just need to -wrap in a call to `graphQLHttp`, a request handler that responds -to GraphQL. - -In *development*, it's also highly recommended to mount the -`graphiQL` handler, which serves GraphQL's official visual -interface, for easy querying and feedback. - -```dart -app.all('/graphql', graphQLHttp(GraphQL(schema))); -app.get('/graphiql', graphiQL()); -``` - -All that's left now is just to start the server! - -```dart -var server = await http.startServer('127.0.0.1', 3000); -var uri = - Uri(scheme: 'http', host: server.address.address, port: server.port); -var graphiqlUri = uri.replace(path: 'graphiql'); -print('Listening at $uri'); -print('Access graphiql at $graphiqlUri'); -``` - -Visit your `/graphiql` endpoint, and you'll see the `graphiql` -UI, ready-to-go! - -![Graphiql screenshot](https://github.com/angel-dart/graphql/raw/master/img/angel_graphql.png) - -Now you're ready to build a GraphQL API! - -## Subscriptions -Example: -https://github.com/angel-dart/graphql/blob/master/angel_graphql/example/subscription.dart - -In GraphQL, as of the June 2018 spec, clients can subscribe to streams of events -from the server. In your schema, all you need to do is return a `Stream` from a `resolve` -callback, rather than a plain object: - -```dart -var postAdded = postService.afterCreated - .asStream() - .map((e) => {'postAdded': e.result}) - .asBroadcastStream(); - -var schema = graphQLSchema( - // ... - subscriptionType: objectType( - 'Subscription', - fields: [ - field('postAdded', postType, resolve: (_, __) => postAdded), - ], - ), -); -``` - -By default, `graphQLHttp` has no support for subscriptions, because regular -HTTP requests are stateless, and are not ideal for continuous data pushing. -You can add your own handler: - -```dart -graphQLHttp(graphQL, onSubscription: (req, res, stream) { - // Do something with the stream here. It's up to you. -}); -``` - -There is, however, `graphQLWS`, which implements Apollo's -`subscriptions-transport-ws` protocol: - -```dart -app.get('/subscriptions', graphQLWS(GraphQL(schema))); -``` - -You can then use existing JavaScript clients to handle subscriptions. - -The `graphiQL` handler also supports using subscriptions. In the following snippet, the -necessary scripts will be added to the rendered page, so that the `subscriptions-transport-ws` -client can be used by GraphiQL: - -```dart -app.get('/graphiql', - graphiQL(subscriptionsEndpoint: 'ws://localhost:3000/subscriptions')); -``` - -**NOTE: Apollo's spec for the aforementioned protocol is very far outdated, and completely inaccurate,** -**See this issue for more:** -**https://github.com/apollographql/subscriptions-transport-ws/issues/551** - -## Using Services -What would Angel be without services? For those unfamiliar - in Angel, -`Service` is a base class that implements CRUD functionality, and serves -as the database interface within an Angel application. They are well-suited -for NoSQL or other databases without a schema (they can be used with -SQL, but that's not their primary focus). - -`package:angel_graphql` has functionality to resolve fields by interacting with -services. - -Consider our previous example, and note the calls to -`resolveViaServiceIndex` and `resolveViaServiceRead`: - -```dart -var queryType = objectType( - 'Query', - description: 'A simple API that manages your to-do list.', - fields: [ - field( - 'todos', - listOf(convertDartType(Todo).nonNullable()), - resolve: resolveViaServiceIndex(todoService), - ), - field( - 'todo', - convertDartType(Todo), - resolve: resolveViaServiceRead(todoService), - inputs: [ - GraphQLFieldInput('id', graphQLId.nonNullable()), - ], - ), - ], - ); -``` - -In all, there are: -* `resolveViaServiceIndex` -* `resolveViaServiceFindOne` -* `resolveViaServiceRead` -* `resolveViaServiceCreate` -* `resolveViaServiceModify` -* `resolveViaServiceUpdate` -* `resolveViaServiceRemove` - -As one might imagine, using these convenience helpers makes -it much quicker to implement CRUD functionality in a GraphQL -API. - -## Documentation -Using `package:graphql_generator`, you can generate GraphQL schemas for concrete Dart -types: - -```dart -configureServer(Angel app) async { - var schema = graphQLSchema( - queryType: objectType('Query', fields: [ - field('todos', listOf(todoGraphQLType), resolve: (_, __) => ...) - ]); - ); -} - -@graphQLClass -class Todo { - String text; - - @GraphQLDocumentation(description: 'Whether this item is complete.') - bool isComplete; -} -``` - -For more documentation, see: -https://pub.dartlang.org/packages/graphql_generator - -## Mirrors -**NOTE: Mirrors support is deprecated, and will not be updated further.** - -The `convertDartType` function can automatically read the documentation -from a type like the following: - -```dart -@GraphQLDocumentation(description: 'Any object with a .text (String) property.') -abstract class HasText { - String get text; -} - -@serializable -@GraphQLDocumentation( - description: 'A task that might not be completed yet. **Yay! Markdown!**') -class Todo extends Model implements HasText { - String text; - - @GraphQLDocumentation(deprecationReason: 'Use `completion_status` instead.') - bool completed; - - CompletionStatus completionStatus; - - Todo({this.text, this.completed, this.completionStatus}); -} - -@GraphQLDocumentation(description: 'The completion status of a to-do item.') -enum CompletionStatus { COMPLETE, INCOMPLETE } -``` - -You can also manually provide documentation for -parameters and endpoints, via a `description` parameter on almost -all related functions. - -See [`package:graphql_schema`](https://github.com/angel-dart/graphql/tree/master/graphql_schema) -for more documentation. \ No newline at end of file diff --git a/packages/graphql/angel_graphql/analysis_options.yaml b/packages/graphql/angel_graphql/analysis_options.yaml deleted file mode 100644 index c230cee7..00000000 --- a/packages/graphql/angel_graphql/analysis_options.yaml +++ /dev/null @@ -1,4 +0,0 @@ -include: package:pedantic/analysis_options.yaml -analyzer: - strong-mode: - implicit-casts: false \ No newline at end of file diff --git a/packages/graphql/angel_graphql/angel_graphql.iml b/packages/graphql/angel_graphql/angel_graphql.iml deleted file mode 100644 index 0854fb6e..00000000 --- a/packages/graphql/angel_graphql/angel_graphql.iml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/packages/graphql/angel_graphql/example/main.dart b/packages/graphql/angel_graphql/example/main.dart deleted file mode 100644 index 83e788bf..00000000 --- a/packages/graphql/angel_graphql/example/main.dart +++ /dev/null @@ -1,105 +0,0 @@ -// ignore_for_file: deprecated_member_use -import 'package:angel_framework/angel_framework.dart'; -import 'package:angel_framework/http.dart'; -import 'package:angel_graphql/angel_graphql.dart'; -import 'package:angel_serialize/angel_serialize.dart'; -import 'package:graphql_schema/graphql_schema.dart'; -import 'package:graphql_server/graphql_server.dart'; -import 'package:graphql_server/mirrors.dart'; -import 'package:logging/logging.dart'; - -main() async { - var logger = Logger('angel_graphql'); - var app = Angel( - logger: logger - ..onRecord.listen((rec) { - print(rec); - if (rec.error != null) print(rec.error); - if (rec.stackTrace != null) print(rec.stackTrace); - })); - var http = AngelHttp(app); - - var todoService = app.use('api/todos', MapService()); - - var queryType = objectType( - 'Query', - description: 'A simple API that manages your to-do list.', - fields: [ - field( - 'todos', - listOf(convertDartType(Todo).nonNullable()), - resolve: resolveViaServiceIndex(todoService), - ), - field( - 'todo', - convertDartType(Todo), - resolve: resolveViaServiceRead(todoService), - inputs: [ - GraphQLFieldInput('id', graphQLId.nonNullable()), - ], - ), - ], - ); - - var mutationType = objectType( - 'Mutation', - description: 'Modify the to-do list.', - fields: [ - field( - 'createTodo', - convertDartType(Todo), - inputs: [ - GraphQLFieldInput( - 'data', convertDartType(Todo).coerceToInputObject()), - ], - resolve: resolveViaServiceCreate(todoService), - ), - ], - ); - - var schema = graphQLSchema( - queryType: queryType, - mutationType: mutationType, - ); - - app.all('/graphql', graphQLHttp(GraphQL(schema))); - app.get('/graphiql', graphiQL()); - - await todoService - .create({'text': 'Clean your room!', 'completion_status': 'COMPLETE'}); - await todoService.create( - {'text': 'Take out the trash', 'completion_status': 'INCOMPLETE'}); - await todoService.create({ - 'text': 'Become a billionaire at the age of 5', - 'completion_status': 'INCOMPLETE' - }); - - var server = await http.startServer('127.0.0.1', 3000); - var uri = - Uri(scheme: 'http', host: server.address.address, port: server.port); - var graphiqlUri = uri.replace(path: 'graphiql'); - print('Listening at $uri'); - print('Access graphiql at $graphiqlUri'); -} - -@GraphQLDocumentation(description: 'Any object with a .text (String) property.') -abstract class HasText { - String get text; -} - -@serializable -@GraphQLDocumentation( - description: 'A task that might not be completed yet. **Yay! Markdown!**') -class Todo extends Model implements HasText { - String text; - - @GraphQLDocumentation(deprecationReason: 'Use `completion_status` instead.') - bool completed; - - CompletionStatus completionStatus; - - Todo({this.text, this.completed, this.completionStatus}); -} - -@GraphQLDocumentation(description: 'The completion status of a to-do item.') -enum CompletionStatus { COMPLETE, INCOMPLETE } diff --git a/packages/graphql/angel_graphql/example/subscription.dart b/packages/graphql/angel_graphql/example/subscription.dart deleted file mode 100644 index cde9634e..00000000 --- a/packages/graphql/angel_graphql/example/subscription.dart +++ /dev/null @@ -1,98 +0,0 @@ -// Inspired by: -// https://www.apollographql.com/docs/apollo-server/features/subscriptions/#subscriptions-example - -import 'package:angel_file_service/angel_file_service.dart'; -import 'package:angel_framework/angel_framework.dart'; -import 'package:angel_framework/http.dart'; -import 'package:angel_graphql/angel_graphql.dart'; -import 'package:file/local.dart'; -import 'package:graphql_schema/graphql_schema.dart'; -import 'package:graphql_server/graphql_server.dart'; -import 'package:logging/logging.dart'; - -main() async { - var logger = Logger('angel_graphql'); - var app = Angel(logger: logger); - var http = AngelHttp(app); - app.logger.onRecord.listen((rec) { - print(rec); - if (rec.error != null) print(rec.error); - if (rec.stackTrace != null) print(rec.stackTrace); - }); - - // Create an in-memory service. - var fs = LocalFileSystem(); - var postService = - app.use('/api/posts', JsonFileService(fs.file('posts.json'))); - - // Also get a [Stream] of item creation events. - var postAdded = postService.afterCreated - .asStream() - .map((e) => {'postAdded': e.result}) - .asBroadcastStream(); - - // GraphQL setup. - var postType = objectType('Post', fields: [ - field('author', graphQLString), - field('comment', graphQLString), - ]); - - var schema = graphQLSchema( - // Hooked up to the postService: - // type Query { posts: [Post] } - queryType: objectType( - 'Query', - fields: [ - field( - 'posts', - listOf(postType), - resolve: resolveViaServiceIndex(postService), - ), - ], - ), - - // Hooked up to the postService: - // type Mutation { - // addPost(author: String!, comment: String!): Post - // } - mutationType: objectType( - 'Mutation', - fields: [ - field( - 'addPost', - postType, - inputs: [ - GraphQLFieldInput( - 'data', postType.toInputObject('PostInput').nonNullable()), - ], - resolve: resolveViaServiceCreate(postService), - ), - ], - ), - - // Hooked up to `postAdded`: - // type Subscription { postAdded: Post } - subscriptionType: objectType( - 'Subscription', - fields: [ - field('postAdded', postType, resolve: (_, __) => postAdded), - ], - ), - ); - - // Mount GraphQL routes; we'll support HTTP and WebSockets transports. - app.all('/graphql', graphQLHttp(GraphQL(schema))); - app.get('/subscriptions', - graphQLWS(GraphQL(schema), keepAliveInterval: Duration(seconds: 3))); - app.get('/graphiql', - graphiQL(subscriptionsEndpoint: 'ws://localhost:3000/subscriptions')); - - var server = await http.startServer('127.0.0.1', 3000); - var uri = - Uri(scheme: 'http', host: server.address.address, port: server.port); - var graphiqlUri = uri.replace(path: 'graphiql'); - var postsUri = uri.replace(pathSegments: ['api', 'posts']); - print('Listening at $uri'); - print('Access graphiql at $graphiqlUri'); - print('Access posts service at $postsUri'); -} diff --git a/packages/graphql/angel_graphql/lib/angel_graphql.dart b/packages/graphql/angel_graphql/lib/angel_graphql.dart deleted file mode 100644 index 780cc100..00000000 --- a/packages/graphql/angel_graphql/lib/angel_graphql.dart +++ /dev/null @@ -1,46 +0,0 @@ -import 'package:angel_framework/angel_framework.dart'; -import 'package:graphql_schema/graphql_schema.dart'; -export 'src/graphiql.dart'; -export 'src/graphql_http.dart'; -export 'src/graphql_ws.dart'; -export 'src/resolvers.dart'; - -/// The canonical [GraphQLUploadType] instance. -final GraphQLUploadType graphQLUpload = GraphQLUploadType(); - -/// A [GraphQLScalarType] that is used to read uploaded files from -/// `multipart/form-data` requests. -class GraphQLUploadType extends GraphQLScalarType { - @override - String get name => 'Upload'; - - @override - String get description => - 'Represents a file that has been uploaded to the server.'; - - @override - GraphQLType coerceToInputObject() => this; - - @override - UploadedFile deserialize(UploadedFile serialized) => serialized; - - @override - UploadedFile serialize(UploadedFile value) => value; - - @override - ValidationResult validate(String key, UploadedFile input) { - if (input != null && input is! UploadedFile) { - return _Vr(false, errors: ['Expected "$key" to be a boolean.']); - } - return _Vr(true, value: input); - } -} - -// TODO: Really need to make the validation result constructors *public* -class _Vr implements ValidationResult { - final bool successful; - final List errors; - final T value; - - _Vr(this.successful, {this.errors, this.value}); -} diff --git a/packages/graphql/angel_graphql/lib/src/graphiql.dart b/packages/graphql/angel_graphql/lib/src/graphiql.dart deleted file mode 100644 index d64b8b4d..00000000 --- a/packages/graphql/angel_graphql/lib/src/graphiql.dart +++ /dev/null @@ -1,89 +0,0 @@ -import 'package:angel_framework/angel_framework.dart'; -import 'package:http_parser/http_parser.dart'; - -/// Returns a simple [RequestHandler] that renders the GraphiQL visual interface for GraphQL. -/// -/// By default, the interface expects your backend to be mounted at `/graphql`; this is configurable -/// via [graphQLEndpoint]. -RequestHandler graphiQL( - {String graphQLEndpoint = '/graphql', String subscriptionsEndpoint}) { - return (req, res) { - res - ..contentType = MediaType('text', 'html') - ..write(renderGraphiql( - graphqlEndpoint: graphQLEndpoint, - subscriptionsEndpoint: subscriptionsEndpoint)) - ..close(); - }; -} - -String renderGraphiql( - {String graphqlEndpoint = '/graphql', String subscriptionsEndpoint}) { - var subscriptionsScripts = '', - subscriptionsFetcher = '', - fetcherName = 'graphQLFetcher'; - - if (subscriptionsEndpoint != null) { - fetcherName = 'subscriptionsFetcher'; - subscriptionsScripts = ''' - - - '''; - subscriptionsFetcher = ''' - let subscriptionsClient = window.SubscriptionsTransportWs.SubscriptionClient('$subscriptionsEndpoint', { - reconnect: true - }); - let $fetcherName = window.GraphiQLSubscriptionsFetcher.graphQLFetcher(subscriptionsClient, graphQLFetcher); - '''; - } - - return ''' - - - - - Angel GraphQL - - - - -
- - - - -$subscriptionsScripts - - - -''' - .trim(); -} diff --git a/packages/graphql/angel_graphql/lib/src/graphql_http.dart b/packages/graphql/angel_graphql/lib/src/graphql_http.dart deleted file mode 100644 index 699b28a5..00000000 --- a/packages/graphql/angel_graphql/lib/src/graphql_http.dart +++ /dev/null @@ -1,182 +0,0 @@ -import 'dart:async'; -import 'dart:convert'; -import 'dart:io'; -import 'package:angel_framework/angel_framework.dart'; -import 'package:angel_validate/server.dart'; -import 'package:graphql_parser/graphql_parser.dart'; -import 'package:graphql_schema/graphql_schema.dart'; -import 'package:graphql_server/graphql_server.dart'; - -final ContentType graphQlContentType = ContentType('application', 'graphql'); - -final Validator graphQlPostBody = Validator({ - 'query*': isNonEmptyString, - 'operation_name': isNonEmptyString, - 'variables': predicate((v) => v == null || v is String || v is Map), -}); - -final RegExp _num = RegExp(r'^[0-9]+$'); - -/// A [RequestHandler] that serves a spec-compliant GraphQL backend. -/// -/// Follows the guidelines listed here: -/// https://graphql.org/learn/serving-over-http/ -RequestHandler graphQLHttp(GraphQL graphQL, - {Function(RequestContext, ResponseContext, Stream>) - onSubscription}) { - return (req, res) async { - var globalVariables = { - '__requestctx': req, - '__responsectx': res, - }; - - sendGraphQLResponse(result) async { - if (result is Stream>) { - if (onSubscription == null) { - throw StateError( - 'The GraphQL backend returned a Stream, but no `onSubscription` callback was provided.'); - } else { - return await onSubscription(req, res, result); - } - } - - return { - 'data': result, - }; - } - - executeMap(Map map) async { - var body = await req.parseBody().then((_) => req.bodyAsMap); - var text = body['query'] as String; - var operationName = body['operation_name'] as String; - var variables = body['variables']; - - if (variables is String) { - variables = json.decode(variables as String); - } - - return await sendGraphQLResponse(await graphQL.parseAndExecute( - text, - sourceUrl: 'input', - operationName: operationName, - variableValues: foldToStringDynamic(variables as Map), - globalVariables: globalVariables, - )); - } - - try { - if (req.method == 'GET') { - if (await validateQuery(graphQlPostBody)(req, res) as bool) { - return await executeMap(req.queryParameters); - } - } else if (req.method == 'POST') { - if (req.headers.contentType?.mimeType == graphQlContentType.mimeType) { - var text = await req.body.transform(utf8.decoder).join(); - return sendGraphQLResponse(await graphQL.parseAndExecute( - text, - sourceUrl: 'input', - globalVariables: globalVariables, - )); - } else if (req.headers.contentType?.mimeType == 'application/json') { - if (await validate(graphQlPostBody)(req, res) as bool) { - return await executeMap(req.bodyAsMap); - } - } else if (req.headers.contentType?.mimeType == 'multipart/form-data') { - var fields = await req.parseBody().then((_) => req.bodyAsMap); - var operations = fields['operations'] as String; - if (operations == null) { - throw AngelHttpException.badRequest( - message: 'Missing "operations" field.'); - } - var map = fields.containsKey('map') - ? json.decode(fields['map'] as String) - : null; - if (map is! Map) { - throw AngelHttpException.badRequest( - message: '"map" field must decode to a JSON object.'); - } - var variables = Map.from(globalVariables); - for (var entry in (map as Map).entries) { - var file = req.uploadedFiles - .firstWhere((f) => f.name == entry.key, orElse: () => null); - if (file == null) { - throw AngelHttpException.badRequest( - message: - '"map" contained key "${entry.key}", but no uploaded file ' - 'has that name.'); - } - if (entry.value is! List) { - throw AngelHttpException.badRequest( - message: - 'The value for "${entry.key}" in the "map" field was not a JSON array.'); - } - var objectPaths = entry.value as List; - for (var objectPath in objectPaths) { - var subPaths = (objectPath as String).split('.'); - if (subPaths[0] == 'variables') { - Object current = variables; - for (int i = 1; i < subPaths.length; i++) { - var name = subPaths[i]; - var parent = subPaths.take(i).join('.'); - if (_num.hasMatch(name)) { - if (current is! List) { - throw AngelHttpException.badRequest( - message: - 'Object "$parent" is not a JSON array, but the ' - '"map" field contained a mapping to $parent.$name.'); - } - (current as List)[int.parse(name)] = file; - } else { - if (current is! Map) { - throw AngelHttpException.badRequest( - message: - 'Object "$parent" is not a JSON object, but the ' - '"map" field contained a mapping to $parent.$name.'); - } - (current as Map)[name] = file; - } - } - } else { - throw AngelHttpException.badRequest( - message: - 'All array values in the "map" field must begin with "variables.".'); - } - } - } - return await sendGraphQLResponse(await graphQL.parseAndExecute( - operations, - sourceUrl: 'input', - globalVariables: variables, - )); - } else { - throw AngelHttpException.badRequest(); - } - } else { - throw AngelHttpException.badRequest(); - } - } on ValidationException catch (e) { - var errors = [GraphQLExceptionError(e.message)]; - - errors.addAll(e.errors.map((ee) => GraphQLExceptionError(ee)).toList()); - return GraphQLException(errors).toJson(); - } on AngelHttpException catch (e) { - var errors = [GraphQLExceptionError(e.message)]; - - errors.addAll(e.errors.map((ee) => GraphQLExceptionError(ee)).toList()); - return GraphQLException(errors).toJson(); - } on SyntaxError catch (e) { - return GraphQLException.fromSourceSpan(e.message, e.span); - } on GraphQLException catch (e) { - return e.toJson(); - } catch (e, st) { - if (req.app?.logger != null) { - req.app.logger.severe( - 'An error occurred while processing GraphQL query at ${req.uri}.', - e, - st); - } - - return GraphQLException.fromMessage(e.toString()).toJson(); - } - }; -} diff --git a/packages/graphql/angel_graphql/lib/src/graphql_ws.dart b/packages/graphql/angel_graphql/lib/src/graphql_ws.dart deleted file mode 100644 index 29f8ba2d..00000000 --- a/packages/graphql/angel_graphql/lib/src/graphql_ws.dart +++ /dev/null @@ -1,80 +0,0 @@ -import 'dart:async'; -import 'dart:io'; -import 'package:angel_framework/angel_framework.dart'; -import 'package:angel_framework/http.dart'; -import 'package:graphql_schema/graphql_schema.dart'; -import 'package:graphql_server/graphql_server.dart'; -import 'package:graphql_server/subscriptions_transport_ws.dart' as stw; -import 'package:web_socket_channel/io.dart'; - -/// A [RequestHandler] that serves a spec-compliant GraphQL backend, over WebSockets. -/// This endpoint only supports WebSockets, and can be used to deliver subscription events. -/// -/// `graphQLWS` uses the Apollo WebSocket protocol, for the sake of compatibility with -/// existing tooling. -/// -/// See: -/// * https://github.com/apollographql/subscriptions-transport-ws -RequestHandler graphQLWS(GraphQL graphQL, {Duration keepAliveInterval}) { - return (req, res) async { - if (req is HttpRequestContext) { - if (WebSocketTransformer.isUpgradeRequest(req.rawRequest)) { - await res.detach(); - var socket = await WebSocketTransformer.upgrade(req.rawRequest, - protocolSelector: (protocols) { - if (protocols.contains('graphql-ws')) { - return 'graphql-ws'; - } else { - throw AngelHttpException.badRequest( - message: 'Only the "graphql-ws" protocol is allowed.'); - } - }); - var channel = IOWebSocketChannel(socket); - var client = stw.RemoteClient(channel.cast()); - var server = - _GraphQLWSServer(client, graphQL, req, res, keepAliveInterval); - await server.done; - } else { - throw AngelHttpException.badRequest( - message: 'The `graphQLWS` endpoint only accepts WebSockets.'); - } - } else { - throw AngelHttpException.badRequest( - message: 'The `graphQLWS` endpoint only accepts HTTP/1.1 requests.'); - } - }; -} - -class _GraphQLWSServer extends stw.Server { - final GraphQL graphQL; - final RequestContext req; - final ResponseContext res; - - _GraphQLWSServer(stw.RemoteClient client, this.graphQL, this.req, this.res, - Duration keepAliveInterval) - : super(client, keepAliveInterval: keepAliveInterval); - - @override - bool onConnect(stw.RemoteClient client, [Map connectionParams]) => true; - - @override - Future onOperation(String id, String query, - [Map variables, String operationName]) async { - try { - var globalVariables = { - '__requestctx': req, - '__responsectx': res, - }; - var data = await graphQL.parseAndExecute( - query, - operationName: operationName, - sourceUrl: 'input', - globalVariables: globalVariables, - variableValues: variables, - ); - return stw.GraphQLResult(data); - } on GraphQLException catch (e) { - return stw.GraphQLResult(null, errors: e.errors); - } - } -} diff --git a/packages/graphql/angel_graphql/lib/src/resolvers.dart b/packages/graphql/angel_graphql/lib/src/resolvers.dart deleted file mode 100644 index 6f789637..00000000 --- a/packages/graphql/angel_graphql/lib/src/resolvers.dart +++ /dev/null @@ -1,143 +0,0 @@ -import 'package:angel_framework/angel_framework.dart'; -import 'package:graphql_schema/graphql_schema.dart'; - -Map _fetchRequestInfo(Map arguments) { - return { - '__requestctx': arguments.remove('__requestctx'), - '__responsectx': arguments.remove('__responsectx'), - }; -} - -Map _getQuery(Map arguments) { - var f = Map.from(arguments)..remove('id')..remove('data'); - return f.isEmpty ? null : f; -} - -/// A GraphQL resolver that `index`es an Angel service. -/// -/// The arguments passed to the resolver will be forwarded to the service, and the -/// service will receive [Providers.graphql]. -GraphQLFieldResolver, Serialized> - resolveViaServiceIndex(Service service) { - return (_, arguments) async { - var _requestInfo = _fetchRequestInfo(arguments); - var params = {'query': _getQuery(arguments), 'provider': Providers.graphQL} - ..addAll(_requestInfo); - - return await service.index(params); - }; -} - -/// A GraphQL resolver that calls `findOne` on an Angel service. -/// -/// The arguments passed to the resolver will be forwarded to the service, and the -/// service will receive [Providers.graphql]. -GraphQLFieldResolver - resolveViaServiceFindOne( - Service service) { - return (_, arguments) async { - var _requestInfo = _fetchRequestInfo(arguments); - var params = {'query': _getQuery(arguments), 'provider': Providers.graphQL} - ..addAll(_requestInfo); - return await service.findOne(params); - }; -} - -/// A GraphQL resolver that `read`s a single value from an Angel service. -/// -/// This resolver should be used on a field with at least the following inputs: -/// * `id`: a [graphQLId] or [graphQLString] -/// -/// The arguments passed to the resolver will be forwarded to the service, and the -/// service will receive [Providers.graphql]. -GraphQLFieldResolver - resolveViaServiceRead(Service service, - {String idField = 'id'}) { - return (_, arguments) async { - var _requestInfo = _fetchRequestInfo(arguments); - var params = {'query': _getQuery(arguments), 'provider': Providers.graphQL} - ..addAll(_requestInfo); - var id = arguments.remove(idField); - return await service.read(id, params); - }; -} - -/// A GraphQL resolver that `creates` a single value in an Angel service. -/// -/// This resolver should be used on a field with at least the following input: -/// * `data`: a [GraphQLObjectType] corresponding to the format of `data` to be passed to `create` -/// -/// The arguments passed to the resolver will be forwarded to the service, and the -/// service will receive [Providers.graphql]. -GraphQLFieldResolver - resolveViaServiceCreate( - Service service) { - return (_, arguments) async { - var _requestInfo = _fetchRequestInfo(arguments); - var params = {'query': _getQuery(arguments), 'provider': Providers.graphQL} - ..addAll(_requestInfo); - return await service.create(arguments['data'] as Value, params); - }; -} - -/// A GraphQL resolver that `modifies` a single value from an Angel service. -/// -/// This resolver should be used on a field with at least the following inputs: -/// * `id`: a [graphQLId] or [graphQLString] -/// * `data`: a [GraphQLObjectType] corresponding to the format of `data` to be passed to `modify` -/// -/// The arguments passed to the resolver will be forwarded to the service, and the -/// service will receive [Providers.graphql]. -GraphQLFieldResolver - resolveViaServiceModify(Service service, - {String idField = 'id'}) { - return (_, arguments) async { - var _requestInfo = _fetchRequestInfo(arguments); - var params = {'query': _getQuery(arguments), 'provider': Providers.graphQL} - ..addAll(_requestInfo); - var id = arguments.remove(idField); - return await service.modify(id, arguments['data'] as Value, params); - }; -} - -/// A GraphQL resolver that `update`s a single value from an Angel service. -/// -/// This resolver should be used on a field with at least the following inputs: -/// * `id`: a [graphQLId] or [graphQLString] -/// * `data`: a [GraphQLObjectType] corresponding to the format of `data` to be passed to `update` -/// -/// The arguments passed to the resolver will be forwarded to the service, and the -/// service will receive [Providers.graphql]. -/// -/// Keep in mind that `update` **overwrites** existing contents. -/// To avoid this, use [resolveViaServiceModify] instead. -GraphQLFieldResolver - resolveViaServiceUpdate(Service service, - {String idField = 'id'}) { - return (_, arguments) async { - var _requestInfo = _fetchRequestInfo(arguments); - var params = {'query': _getQuery(arguments), 'provider': Providers.graphQL} - ..addAll(_requestInfo); - var id = arguments.remove(idField); - return await service.update(id, arguments['data'] as Value, params); - }; -} - -/// A GraphQL resolver that `remove`s a single value from an Angel service. -/// -/// This resolver should be used on a field with at least the following inputs: -/// * `id`: a [graphQLId] or [graphQLString] -/// -/// The arguments passed to the resolver will be forwarded to the service, and the -/// service will receive [Providers.graphql]. -GraphQLFieldResolver - resolveViaServiceRemove(Service service, - {String idField = 'id'}) { - return (_, arguments) async { - var _requestInfo = _fetchRequestInfo(arguments); - var params = {'query': _getQuery(arguments), 'provider': Providers.graphQL} - ..addAll(_requestInfo); - var id = arguments.remove(idField); - return await service.remove(id, params); - }; -} diff --git a/packages/graphql/angel_graphql/mono_pkg.yaml b/packages/graphql/angel_graphql/mono_pkg.yaml deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/graphql/angel_graphql/pubspec.yaml b/packages/graphql/angel_graphql/pubspec.yaml deleted file mode 100644 index 934315a3..00000000 --- a/packages/graphql/angel_graphql/pubspec.yaml +++ /dev/null @@ -1,32 +0,0 @@ -name: angel_graphql -version: 1.1.0 -description: The fastest + easiest way to get a GraphQL backend in Dart, using Angel. -homepage: https://github.com/angel-dart/graphql -author: Tobe O -environment: - sdk: '>=2.10.0 <2.12.0' -dependencies: - angel_file_service: #^2.0.0 - path: ../../file_service - angel_framework: #^2.0.0 - path: ../../framework - angel_websocket: #^2.0.0 - path: ../../websocket - angel_validate: #^2.0.0 - path: ../../validate - graphql_parser: #^1.0.0 - path: ../graphql_parser - graphql_schema: #^1.0.0 - path: ../graphql_schema - graphql_server: #^1.0.0 - path: ../graphql_server - http_parser: ^3.0.0 - web_socket_channel: ^1.0.0 -dev_dependencies: - angel_serialize: #^2.0.0 - path: ../../serialize/angel_serialize - file: ^5.0.0 - logging: ^0.11.0 - pedantic: ^1.0.0 - - \ No newline at end of file diff --git a/packages/graphql/data_loader/.gitignore b/packages/graphql/data_loader/.gitignore deleted file mode 100644 index 1f45969e..00000000 --- a/packages/graphql/data_loader/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -.packages -pubspec.lock -.dart_tool -doc/api \ No newline at end of file diff --git a/packages/graphql/data_loader/CHANGELOG.md b/packages/graphql/data_loader/CHANGELOG.md deleted file mode 100644 index 92642921..00000000 --- a/packages/graphql/data_loader/CHANGELOG.md +++ /dev/null @@ -1,2 +0,0 @@ -# 1.0.0 -* Initial version. \ No newline at end of file diff --git a/packages/graphql/data_loader/LICENSE b/packages/graphql/data_loader/LICENSE deleted file mode 100644 index 89074fd3..00000000 --- a/packages/graphql/data_loader/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2017 The Angel Framework - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/packages/graphql/data_loader/README.md b/packages/graphql/data_loader/README.md deleted file mode 100644 index 7d8c5ce7..00000000 --- a/packages/graphql/data_loader/README.md +++ /dev/null @@ -1,26 +0,0 @@ -# data_loader -[![Pub](https://img.shields.io/pub/v/data_loader.svg)](https://pub.dartlang.org/packages/data_loader) -[![build status](https://travis-ci.org/angel-dart/graphql.svg)](https://travis-ci.org/angel-dart/graphql) - - -Batch and cache database lookups. Works well with GraphQL. -Ported from the original JS version: -https://github.com/graphql/dataloader - -## Installation -In your pubspec.yaml: - -```yaml -dependencies: - data_loader: ^1.0.0 -``` - -## Usage -Complete example: -https://github.com/angel-dart/graphql/blob/master/data_loader/example/main.dart - -```dart -var userLoader = new DataLoader((key) => myBatchGetUsers(keys)); -var invitedBy = await userLoader.load(1)then(user => userLoader.load(user.invitedByID)) -print('User 1 was invited by $invitedBy')); -``` \ No newline at end of file diff --git a/packages/graphql/data_loader/analysis_options.yaml b/packages/graphql/data_loader/analysis_options.yaml deleted file mode 100644 index c230cee7..00000000 --- a/packages/graphql/data_loader/analysis_options.yaml +++ /dev/null @@ -1,4 +0,0 @@ -include: package:pedantic/analysis_options.yaml -analyzer: - strong-mode: - implicit-casts: false \ No newline at end of file diff --git a/packages/graphql/data_loader/example/main.dart b/packages/graphql/data_loader/example/main.dart deleted file mode 100644 index 2121bb23..00000000 --- a/packages/graphql/data_loader/example/main.dart +++ /dev/null @@ -1,44 +0,0 @@ -import 'dart:async'; -import 'package:data_loader/data_loader.dart'; -import 'package:graphql_schema/graphql_schema.dart'; - -external Future> fetchTodos(Iterable ids); - -main() async { - // Create a DataLoader. By default, it caches lookups. - var todoLoader = DataLoader(fetchTodos); // DataLoader - - // type Todo { id: Int, text: String, is_complete: Boolean } - var todoType = objectType( - 'Todo', - fields: [ - field('id', graphQLInt), - field('text', graphQLString), - field('is_complete', graphQLBoolean), - ], - ); - - // type Query { todo($id: Int!) Todo } - // ignore: unused_local_variable - var schema = graphQLSchema( - queryType: objectType( - 'Query', - fields: [ - field( - 'todo', - listOf(todoType), - inputs: [GraphQLFieldInput('id', graphQLInt.nonNullable())], - resolve: (_, args) => todoLoader.load(args['id'] as int), - ), - ], - ), - ); - - // Do something with your schema... -} - -abstract class Todo { - int get id; - String get text; - bool get isComplete; -} diff --git a/packages/graphql/data_loader/lib/data_loader.dart b/packages/graphql/data_loader/lib/data_loader.dart deleted file mode 100644 index c806f908..00000000 --- a/packages/graphql/data_loader/lib/data_loader.dart +++ /dev/null @@ -1,94 +0,0 @@ -import 'dart:async'; -import 'dart:collection'; - -/// A utility for batching multiple requests together, to improve application performance. -/// -/// Enqueues batches of requests until the next tick, when they are processed in bulk. -/// -/// Port of Facebook's `DataLoader`: -/// https://github.com/graphql/dataloader -class DataLoader { - /// Invoked to fetch a batch of keys simultaneously. - final FutureOr> Function(Iterable) loadMany; - - /// Whether to use a memoization cache to store the results of past lookups. - final bool cache; - - var _cache = {}; - var _queue = Queue<_QueueItem>(); - bool _started = false; - - DataLoader(this.loadMany, {this.cache = true}); - - Future _onTick() async { - if (_queue.isNotEmpty) { - var current = _queue.toList(); - _queue.clear(); - - List loadIds = - current.map((i) => i.id).toSet().toList(growable: false); - - var data = await loadMany( - loadIds, - ); - - for (int i = 0; i < loadIds.length; i++) { - var id = loadIds[i]; - var value = data.elementAt(i); - - if (cache) _cache[id] = value; - - current - .where((item) => item.id == id) - .forEach((item) => item.completer.complete(value)); - } - } - - _started = false; - // if (!_closed) scheduleMicrotask(_onTick); - } - - /// Clears the value at [key], if it exists. - void clear(Id key) => _cache.remove(key); - - /// Clears the entire cache. - void clearAll() => _cache.clear(); - - /// Primes the cache with the provided key and value. If the key already exists, no change is made. - /// - /// To forcefully prime the cache, clear the key first with - /// `loader..clear(key)..prime(key, value)`. - void prime(Id key, Data value) => _cache.putIfAbsent(key, () => value); - - /// Closes this [DataLoader], cancelling all pending requests. - void close() { - while (_queue.isNotEmpty) { - _queue.removeFirst().completer.completeError( - StateError('The DataLoader was closed before the item was loaded.')); - } - - _queue.clear(); - } - - /// Returns a [Future] that completes when the next batch of requests completes. - Future load(Id id) { - if (cache && _cache.containsKey(id)) { - return Future.value(_cache[id]); - } else { - var item = _QueueItem(id); - _queue.add(item); - if (!_started) { - _started = true; - scheduleMicrotask(_onTick); - } - return item.completer.future; - } - } -} - -class _QueueItem { - final Id id; - final Completer completer = Completer(); - - _QueueItem(this.id); -} diff --git a/packages/graphql/data_loader/mono_pkg.yaml b/packages/graphql/data_loader/mono_pkg.yaml deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/graphql/data_loader/pubspec.yaml b/packages/graphql/data_loader/pubspec.yaml deleted file mode 100644 index a1839c75..00000000 --- a/packages/graphql/data_loader/pubspec.yaml +++ /dev/null @@ -1,12 +0,0 @@ -name: data_loader -version: 1.0.0 -author: Tobe O -description: Batch and cache database lookups. Works well with GraphQL. Ported from JS. -homepage: https://github.com/angel-dart/graphql -environment: - sdk: '>=2.10.0 <2.12.0' -dev_dependencies: - graphql_schema: #^1.0.0 - path: ../graphql_schema - pedantic: ^1.0.0 - test: ^1.15.7 \ No newline at end of file diff --git a/packages/graphql/data_loader/test/all_test.dart b/packages/graphql/data_loader/test/all_test.dart deleted file mode 100644 index 28f95eda..00000000 --- a/packages/graphql/data_loader/test/all_test.dart +++ /dev/null @@ -1,100 +0,0 @@ -import 'dart:async'; - -import 'package:data_loader/data_loader.dart'; -import 'package:test/test.dart'; - -void main() { - var numbers = List.generate(10, (i) => i.toStringAsFixed(2)); - var numberLoader = DataLoader((ids) { - print('ID batch: $ids'); - return ids.map((i) => numbers[i]); - }); - - test('batch', () async { - var zero = numberLoader.load(0); - var one = numberLoader.load(1); - var two = numberLoader.load(2); - var batch = await Future.wait([zero, one, two]); - print('Fetched result: $batch'); - expect(batch, ['0.00', '1.00', '2.00']); - }); - - test('dedupe', () async { - var loader = DataLoader>>((ids) { - return ids.map( - (i) => {i: ids.toList()}, - ); - }); - - var zero = loader.load(0); - var one = loader.load(1); - var two = loader.load(2); - var anotherZero = loader.load(0); - var batch = await Future.wait([zero, one, two, anotherZero]); - - expect( - batch, - [ - { 0: [0, 1, 2]}, - { 1: [0, 1, 2]}, - { 2: [0, 1, 2]}, - { 0: [0, 1, 2]}, - ], - ); - }); - - group('cache', () { - DataLoader uniqueLoader, noCache; - - setUp(() { - uniqueLoader = DataLoader((ids) async { - var numbers = await numberLoader.loadMany(ids); - return numbers.map((s) => _Unique(s)); - }); - noCache = DataLoader(uniqueLoader.loadMany, cache: false); - }); - - tearDown(() { - uniqueLoader.close(); - noCache.close(); - }); - - test('only lookup once', () async { - var a = await uniqueLoader.load(3); - var b = await uniqueLoader.load(3); - expect(a, b); - }); - - test('can be disabled', () async { - var a = await noCache.load(3); - var b = await noCache.load(3); - expect(a, isNot(b)); - }); - - test('clear', () async { - var a = await uniqueLoader.load(3); - uniqueLoader.clear(3); - var b = await uniqueLoader.load(3); - expect(a, isNot(b)); - }); - - test('clearAll', () async { - var a = await uniqueLoader.load(3); - uniqueLoader.clearAll(); - var b = await uniqueLoader.load(3); - expect(a, isNot(b)); - }); - - test('prime', () async { - uniqueLoader.prime(3, _Unique('hey')); - var a = await uniqueLoader.load(3); - expect(a.value, 'hey'); - }); - }); -} - -class _Unique { - final String value; - - _Unique(this.value); -} diff --git a/packages/graphql/example_star_wars/.gitignore b/packages/graphql/example_star_wars/.gitignore deleted file mode 100644 index 26517d3b..00000000 --- a/packages/graphql/example_star_wars/.gitignore +++ /dev/null @@ -1,93 +0,0 @@ -# See https://www.dartlang.org/tools/private-files.html - -# Files and directories created by pub -.buildlog -.packages -.project -.pub/ -.scripts-bin/ -build/ -**/packages/ - -# Files created by dart2js -# (Most Dart developers will use pub build to compile Dart, use/modify these -# rules if you intend to use dart2js directly -# Convention is to use extension '.dart.js' for Dart compiled to Javascript to -# differentiate from explicit Javascript files) -*.dart.js -*.part.js -*.js.deps -*.js.map -*.info.json - -# Directory created by dartdoc -doc/api/ - -# Don't commit pubspec lock file -# (Library packages only! Remove pattern if developing an application package) -pubspec.lock -### Dart template -# See https://www.dartlang.org/tools/private-files.html - -# Files and directories created by pub - -# SDK 1.20 and later (no longer creates packages directories) - -# Older SDK versions -# (Include if the minimum SDK version specified in pubsepc.yaml is earlier than 1.20) - - -# Files created by dart2js -# (Most Dart developers will use pub build to compile Dart, use/modify these -# rules if you intend to use dart2js directly -# Convention is to use extension '.dart.js' for Dart compiled to Javascript to -# differentiate from explicit Javascript files) - -# Directory created by dartdoc - -# Don't commit pubspec lock file -# (Library packages only! Remove pattern if developing an application package) -### JetBrains template -# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm -# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 - -# User-specific stuff: -../.idea/workspace.xml -.idea/**/tasks.xml -.idea/dictionaries - -# Sensitive or high-churn files: -.idea/**/dataSources/ -.idea/**/dataSources.ids -.idea/**/dataSources.xml -.idea/**/dataSources.local.xml -.idea/**/sqlDataSources.xml -.idea/**/dynamic.xml -.idea/**/uiDesigner.xml - -# Gradle: -.idea/**/gradle.xml -.idea/**/libraries - -# Mongo Explorer plugin: -.idea/**/mongoSettings.xml - -## File-based project format: -*.iws - -## Plugin-specific files: - -# IntelliJ -/out/ - -# mpeltonen/sbt-idea plugin -.idea_modules/ - -# JIRA plugin -atlassian-ide-plugin.xml - -# Crashlytics plugin (for Android Studio and IntelliJ) -com_crashlytics_export_strings.xml -crashlytics.properties -crashlytics-build.properties -fabric.properties diff --git a/packages/graphql/example_star_wars/LICENSE b/packages/graphql/example_star_wars/LICENSE deleted file mode 100644 index 89074fd3..00000000 --- a/packages/graphql/example_star_wars/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2017 The Angel Framework - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/packages/graphql/example_star_wars/analysis_options.yaml b/packages/graphql/example_star_wars/analysis_options.yaml deleted file mode 100644 index eae1e42a..00000000 --- a/packages/graphql/example_star_wars/analysis_options.yaml +++ /dev/null @@ -1,3 +0,0 @@ -analyzer: - strong-mode: - implicit-casts: false \ No newline at end of file diff --git a/packages/graphql/example_star_wars/bin/server.dart b/packages/graphql/example_star_wars/bin/server.dart deleted file mode 100644 index 5e7e0e91..00000000 --- a/packages/graphql/example_star_wars/bin/server.dart +++ /dev/null @@ -1,28 +0,0 @@ -import 'dart:async'; -import 'dart:io'; - -import 'package:angel_framework/angel_framework.dart'; -import 'package:angel_hot/angel_hot.dart'; -import 'package:logging/logging.dart'; -import 'package:star_wars/src/pretty_logging.dart' as star_wars; -import 'package:star_wars/star_wars.dart' as star_wars; - -main() async { - Future createServer() async { - hierarchicalLoggingEnabled = true; - var logger = Logger.detached('star_wars') - ..onRecord.listen(star_wars.prettyLog); - var app = Angel(logger: logger); - await app.configure(star_wars.configureServer); - return app; - } - - var hot = HotReloader(createServer, [Directory('lib')]); - - var server = await hot.startServer('127.0.0.1', 3000); - var serverUrl = - Uri(scheme: 'http', host: server.address.address, port: server.port); - var graphiQLUrl = serverUrl.replace(path: '/graphiql'); - print('Listening at $serverUrl'); - print('GraphiQL endpoint: $graphiQLUrl'); -} diff --git a/packages/graphql/example_star_wars/example_star_wars.iml b/packages/graphql/example_star_wars/example_star_wars.iml deleted file mode 100644 index 75734c90..00000000 --- a/packages/graphql/example_star_wars/example_star_wars.iml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/packages/graphql/example_star_wars/lib/src/models/character.dart b/packages/graphql/example_star_wars/lib/src/models/character.dart deleted file mode 100644 index 89f81888..00000000 --- a/packages/graphql/example_star_wars/lib/src/models/character.dart +++ /dev/null @@ -1,12 +0,0 @@ -import 'package:graphql_schema/graphql_schema.dart'; -import 'episode.dart'; -part 'character.g.dart'; - -@graphQLClass -abstract class Character { - String get id; - - String get name; - - // List get appearsIn; -} diff --git a/packages/graphql/example_star_wars/lib/src/models/character.g.dart b/packages/graphql/example_star_wars/lib/src/models/character.g.dart deleted file mode 100644 index 4a750420..00000000 --- a/packages/graphql/example_star_wars/lib/src/models/character.g.dart +++ /dev/null @@ -1,13 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'character.dart'; - -// ************************************************************************** -// _GraphQLGenerator -// ************************************************************************** - -/// Auto-generated from [Character]. -final GraphQLObjectType characterGraphQLType = objectType('Character', - isInterface: true, - interfaces: [], - fields: [field('id', graphQLString), field('name', graphQLString)]); diff --git a/packages/graphql/example_star_wars/lib/src/models/droid.dart b/packages/graphql/example_star_wars/lib/src/models/droid.dart deleted file mode 100644 index 418aeeef..00000000 --- a/packages/graphql/example_star_wars/lib/src/models/droid.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:angel_model/angel_model.dart'; -import 'package:angel_serialize/angel_serialize.dart'; -import 'package:collection/collection.dart'; -import 'package:graphql_schema/graphql_schema.dart'; -import 'character.dart'; -import 'episode.dart'; -part 'droid.g.dart'; - -@serializable -@graphQLClass -@GraphQLDocumentation(description: 'Beep! Boop!') -abstract class _Droid extends Model implements Character { - String get id; - - String get name; - - @GraphQLDocumentation( - description: 'The list of episodes this droid appears in.') - List get appearsIn; - - /// Doc comments automatically become GraphQL descriptions. - List get friends; -} diff --git a/packages/graphql/example_star_wars/lib/src/models/droid.g.dart b/packages/graphql/example_star_wars/lib/src/models/droid.g.dart deleted file mode 100644 index 2c92c3c4..00000000 --- a/packages/graphql/example_star_wars/lib/src/models/droid.g.dart +++ /dev/null @@ -1,164 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'droid.dart'; - -// ************************************************************************** -// JsonModelGenerator -// ************************************************************************** - -@generatedSerializable -class Droid extends _Droid { - Droid( - {this.id, - this.name, - List appearsIn, - List friends, - this.createdAt, - this.updatedAt}) - : this.appearsIn = new List.unmodifiable(appearsIn ?? []), - this.friends = new List.unmodifiable(friends ?? []); - - @override - final String id; - - @override - final String name; - - @override - final List appearsIn; - - @override - final List friends; - - @override - final DateTime createdAt; - - @override - final DateTime updatedAt; - - Droid copyWith( - {String id, - String name, - List appearsIn, - List friends, - DateTime createdAt, - DateTime updatedAt}) { - return new Droid( - id: id ?? this.id, - name: name ?? this.name, - appearsIn: appearsIn ?? this.appearsIn, - friends: friends ?? this.friends, - createdAt: createdAt ?? this.createdAt, - updatedAt: updatedAt ?? this.updatedAt); - } - - bool operator ==(other) { - return other is _Droid && - other.id == id && - other.name == name && - const ListEquality(const DefaultEquality()) - .equals(other.appearsIn, appearsIn) && - const ListEquality(const DefaultEquality()) - .equals(other.friends, friends) && - other.createdAt == createdAt && - other.updatedAt == updatedAt; - } - - @override - int get hashCode { - return hashObjects([id, name, appearsIn, friends, createdAt, updatedAt]); - } - - Map toJson() { - return DroidSerializer.toMap(this); - } -} - -// ************************************************************************** -// SerializerGenerator -// ************************************************************************** - -abstract class DroidSerializer { - static Droid fromMap(Map map) { - return new Droid( - id: map['id'] as String, - name: map['name'] as String, - appearsIn: map['appears_in'] is Iterable - ? (map['appears_in'] as Iterable).cast().toList() - : null, - friends: map['friends'] is Iterable - ? (map['friends'] as Iterable).cast().toList() - : null, - createdAt: map['created_at'] != null - ? (map['created_at'] is DateTime - ? (map['created_at'] as DateTime) - : DateTime.parse(map['created_at'].toString())) - : null, - updatedAt: map['updated_at'] != null - ? (map['updated_at'] is DateTime - ? (map['updated_at'] as DateTime) - : DateTime.parse(map['updated_at'].toString())) - : null); - } - - static Map toMap(_Droid model) { - if (model == null) { - return null; - } - return { - 'id': model.id, - 'name': model.name, - 'appears_in': model.appearsIn, - 'friends': model.friends, - 'created_at': model.createdAt?.toIso8601String(), - 'updated_at': model.updatedAt?.toIso8601String() - }; - } -} - -abstract class DroidFields { - static const List allFields = [ - id, - name, - appearsIn, - friends, - createdAt, - updatedAt - ]; - - static const String id = 'id'; - - static const String name = 'name'; - - static const String appearsIn = 'appears_in'; - - static const String friends = 'friends'; - - static const String createdAt = 'created_at'; - - static const String updatedAt = 'updated_at'; -} - -// ************************************************************************** -// _GraphQLGenerator -// ************************************************************************** - -/// Auto-generated from [Droid]. -final GraphQLObjectType droidGraphQLType = objectType('Droid', - isInterface: false, - description: 'Beep! Boop!', - interfaces: [ - characterGraphQLType - ], - fields: [ - field('id', graphQLString), - field('name', graphQLString), - field('appears_in', listOf(episodeGraphQLType), - description: 'The list of episodes this droid appears in.'), - field('friends', listOf(characterGraphQLType), - description: - 'Doc comments automatically become GraphQL descriptions.'), - field('created_at', graphQLDate), - field('updated_at', graphQLDate), - field('idAsInt', graphQLInt) - ]); diff --git a/packages/graphql/example_star_wars/lib/src/models/episode.dart b/packages/graphql/example_star_wars/lib/src/models/episode.dart deleted file mode 100644 index d14cc47c..00000000 --- a/packages/graphql/example_star_wars/lib/src/models/episode.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:graphql_schema/graphql_schema.dart'; -part 'episode.g.dart'; - -@GraphQLDocumentation( - description: 'The episodes of the Star Wars original trilogy.') -@graphQLClass -enum Episode { - NEWHOPE, - EMPIRE, - JEDI, -} diff --git a/packages/graphql/example_star_wars/lib/src/models/episode.g.dart b/packages/graphql/example_star_wars/lib/src/models/episode.g.dart deleted file mode 100644 index 74a9a240..00000000 --- a/packages/graphql/example_star_wars/lib/src/models/episode.g.dart +++ /dev/null @@ -1,12 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'episode.dart'; - -// ************************************************************************** -// _GraphQLGenerator -// ************************************************************************** - -/// Auto-generated from [Episode]. -final GraphQLEnumType episodeGraphQLType = enumTypeFromStrings( - 'Episode', const ['NEWHOPE', 'EMPIRE', 'JEDI'], - description: 'The episodes of the Star Wars original trilogy.'); diff --git a/packages/graphql/example_star_wars/lib/src/models/human.dart b/packages/graphql/example_star_wars/lib/src/models/human.dart deleted file mode 100644 index 04e33e41..00000000 --- a/packages/graphql/example_star_wars/lib/src/models/human.dart +++ /dev/null @@ -1,35 +0,0 @@ -import 'package:angel_model/angel_model.dart'; -import 'package:angel_serialize/angel_serialize.dart'; -import 'package:collection/collection.dart'; -import 'package:graphql_schema/graphql_schema.dart'; -import 'character.dart'; -import 'episode.dart'; -part 'human.g.dart'; - -@serializable -@graphQLClass -abstract class _Human extends Model implements Character { - // @GraphQLDocumentation(description: "This human's name, of course.") - // String name; - // List friends; - // List appearsIn; - // List starships; - // int totalCredits; - - String get id; - - String get name; - - List get appearsIn; - - List get friends; - - int get totalCredits; - - // Human( - // {this.name, - // this.friends, - // this.appearsIn, - // this.starships, - // this.totalCredits}); -} diff --git a/packages/graphql/example_star_wars/lib/src/models/human.g.dart b/packages/graphql/example_star_wars/lib/src/models/human.g.dart deleted file mode 100644 index b3cc00a7..00000000 --- a/packages/graphql/example_star_wars/lib/src/models/human.g.dart +++ /dev/null @@ -1,172 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'human.dart'; - -// ************************************************************************** -// JsonModelGenerator -// ************************************************************************** - -@generatedSerializable -class Human extends _Human { - Human( - {this.id, - this.name, - List appearsIn, - List friends, - this.totalCredits, - this.createdAt, - this.updatedAt}) - : this.appearsIn = new List.unmodifiable(appearsIn ?? []), - this.friends = new List.unmodifiable(friends ?? []); - - @override - final String id; - - @override - final String name; - - @override - final List appearsIn; - - @override - final List friends; - - @override - final int totalCredits; - - @override - final DateTime createdAt; - - @override - final DateTime updatedAt; - - Human copyWith( - {String id, - String name, - List appearsIn, - List friends, - int totalCredits, - DateTime createdAt, - DateTime updatedAt}) { - return new Human( - id: id ?? this.id, - name: name ?? this.name, - appearsIn: appearsIn ?? this.appearsIn, - friends: friends ?? this.friends, - totalCredits: totalCredits ?? this.totalCredits, - createdAt: createdAt ?? this.createdAt, - updatedAt: updatedAt ?? this.updatedAt); - } - - bool operator ==(other) { - return other is _Human && - other.id == id && - other.name == name && - const ListEquality(const DefaultEquality()) - .equals(other.appearsIn, appearsIn) && - const ListEquality(const DefaultEquality()) - .equals(other.friends, friends) && - other.totalCredits == totalCredits && - other.createdAt == createdAt && - other.updatedAt == updatedAt; - } - - @override - int get hashCode { - return hashObjects( - [id, name, appearsIn, friends, totalCredits, createdAt, updatedAt]); - } - - Map toJson() { - return HumanSerializer.toMap(this); - } -} - -// ************************************************************************** -// SerializerGenerator -// ************************************************************************** - -abstract class HumanSerializer { - static Human fromMap(Map map) { - return new Human( - id: map['id'] as String, - name: map['name'] as String, - appearsIn: map['appears_in'] is Iterable - ? (map['appears_in'] as Iterable).cast().toList() - : null, - friends: map['friends'] is Iterable - ? (map['friends'] as Iterable).cast().toList() - : null, - totalCredits: map['total_credits'] as int, - createdAt: map['created_at'] != null - ? (map['created_at'] is DateTime - ? (map['created_at'] as DateTime) - : DateTime.parse(map['created_at'].toString())) - : null, - updatedAt: map['updated_at'] != null - ? (map['updated_at'] is DateTime - ? (map['updated_at'] as DateTime) - : DateTime.parse(map['updated_at'].toString())) - : null); - } - - static Map toMap(_Human model) { - if (model == null) { - return null; - } - return { - 'id': model.id, - 'name': model.name, - 'appears_in': model.appearsIn, - 'friends': model.friends, - 'total_credits': model.totalCredits, - 'created_at': model.createdAt?.toIso8601String(), - 'updated_at': model.updatedAt?.toIso8601String() - }; - } -} - -abstract class HumanFields { - static const List allFields = [ - id, - name, - appearsIn, - friends, - totalCredits, - createdAt, - updatedAt - ]; - - static const String id = 'id'; - - static const String name = 'name'; - - static const String appearsIn = 'appears_in'; - - static const String friends = 'friends'; - - static const String totalCredits = 'total_credits'; - - static const String createdAt = 'created_at'; - - static const String updatedAt = 'updated_at'; -} - -// ************************************************************************** -// _GraphQLGenerator -// ************************************************************************** - -/// Auto-generated from [Human]. -final GraphQLObjectType humanGraphQLType = - objectType('Human', isInterface: false, interfaces: [ - characterGraphQLType -], fields: [ - field('id', graphQLString), - field('name', graphQLString), - field('appears_in', listOf(episodeGraphQLType)), - field('friends', listOf(characterGraphQLType)), - field('total_credits', graphQLInt), - field('created_at', graphQLDate), - field('updated_at', graphQLDate), - field('idAsInt', graphQLInt) -]); diff --git a/packages/graphql/example_star_wars/lib/src/models/models.dart b/packages/graphql/example_star_wars/lib/src/models/models.dart deleted file mode 100644 index 5691bef9..00000000 --- a/packages/graphql/example_star_wars/lib/src/models/models.dart +++ /dev/null @@ -1,5 +0,0 @@ -export 'character.dart'; -export 'droid.dart'; -export 'episode.dart'; -export 'human.dart'; -export 'starship.dart'; diff --git a/packages/graphql/example_star_wars/lib/src/models/starship.dart b/packages/graphql/example_star_wars/lib/src/models/starship.dart deleted file mode 100644 index b9888391..00000000 --- a/packages/graphql/example_star_wars/lib/src/models/starship.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:angel_model/angel_model.dart'; -import 'package:angel_serialize/angel_serialize.dart'; -import 'package:graphql_schema/graphql_schema.dart'; -part 'starship.g.dart'; - -@serializable -@graphQLClass -abstract class _Starship extends Model { - String get name; - int get length; -} diff --git a/packages/graphql/example_star_wars/lib/src/models/starship.g.dart b/packages/graphql/example_star_wars/lib/src/models/starship.g.dart deleted file mode 100644 index 4fc3a73e..00000000 --- a/packages/graphql/example_star_wars/lib/src/models/starship.g.dart +++ /dev/null @@ -1,130 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'starship.dart'; - -// ************************************************************************** -// JsonModelGenerator -// ************************************************************************** - -@generatedSerializable -class Starship extends _Starship { - Starship({this.id, this.name, this.length, this.createdAt, this.updatedAt}); - - @override - final String id; - - @override - final String name; - - @override - final int length; - - @override - final DateTime createdAt; - - @override - final DateTime updatedAt; - - Starship copyWith( - {String id, - String name, - int length, - DateTime createdAt, - DateTime updatedAt}) { - return new Starship( - id: id ?? this.id, - name: name ?? this.name, - length: length ?? this.length, - createdAt: createdAt ?? this.createdAt, - updatedAt: updatedAt ?? this.updatedAt); - } - - bool operator ==(other) { - return other is _Starship && - other.id == id && - other.name == name && - other.length == length && - other.createdAt == createdAt && - other.updatedAt == updatedAt; - } - - @override - int get hashCode { - return hashObjects([id, name, length, createdAt, updatedAt]); - } - - Map toJson() { - return StarshipSerializer.toMap(this); - } -} - -// ************************************************************************** -// SerializerGenerator -// ************************************************************************** - -abstract class StarshipSerializer { - static Starship fromMap(Map map) { - return new Starship( - id: map['id'] as String, - name: map['name'] as String, - length: map['length'] as int, - createdAt: map['created_at'] != null - ? (map['created_at'] is DateTime - ? (map['created_at'] as DateTime) - : DateTime.parse(map['created_at'].toString())) - : null, - updatedAt: map['updated_at'] != null - ? (map['updated_at'] is DateTime - ? (map['updated_at'] as DateTime) - : DateTime.parse(map['updated_at'].toString())) - : null); - } - - static Map toMap(_Starship model) { - if (model == null) { - return null; - } - return { - 'id': model.id, - 'name': model.name, - 'length': model.length, - 'created_at': model.createdAt?.toIso8601String(), - 'updated_at': model.updatedAt?.toIso8601String() - }; - } -} - -abstract class StarshipFields { - static const List allFields = [ - id, - name, - length, - createdAt, - updatedAt - ]; - - static const String id = 'id'; - - static const String name = 'name'; - - static const String length = 'length'; - - static const String createdAt = 'created_at'; - - static const String updatedAt = 'updated_at'; -} - -// ************************************************************************** -// _GraphQLGenerator -// ************************************************************************** - -/// Auto-generated from [Starship]. -final GraphQLObjectType starshipGraphQLType = - objectType('Starship', isInterface: false, interfaces: [], fields: [ - field('id', graphQLString), - field('name', graphQLString), - field('length', graphQLInt), - field('created_at', graphQLDate), - field('updated_at', graphQLDate), - field('idAsInt', graphQLInt) -]); diff --git a/packages/graphql/example_star_wars/lib/src/pretty_logging.dart b/packages/graphql/example_star_wars/lib/src/pretty_logging.dart deleted file mode 100644 index 3f8b452d..00000000 --- a/packages/graphql/example_star_wars/lib/src/pretty_logging.dart +++ /dev/null @@ -1,35 +0,0 @@ -import 'package:angel_http_exception/angel_http_exception.dart'; -import 'package:logging/logging.dart'; -import 'package:io/ansi.dart'; - -/// Prints the contents of a [LogRecord] with pretty colors. -void prettyLog(LogRecord record) { - var code = chooseLogColor(record.level); - - if (record.error == null) print(code.wrap(record.toString())); - - if (record.error != null) { - var err = record.error; - if (err is AngelHttpException && err.statusCode != 500) return; - print(code.wrap(record.toString() + '\n')); - print(code.wrap(err.toString())); - - if (record.stackTrace != null) { - print(code.wrap(record.stackTrace.toString())); - } - } -} - -/// Chooses a color based on the logger [level]. -AnsiCode chooseLogColor(Level level) { - if (level == Level.SHOUT) - return backgroundRed; - else if (level == Level.SEVERE) - return red; - else if (level == Level.WARNING) - return yellow; - else if (level == Level.INFO) - return cyan; - else if (level == Level.FINER || level == Level.FINEST) return lightGray; - return resetAll; -} diff --git a/packages/graphql/example_star_wars/lib/star_wars.dart b/packages/graphql/example_star_wars/lib/star_wars.dart deleted file mode 100644 index 31495e02..00000000 --- a/packages/graphql/example_star_wars/lib/star_wars.dart +++ /dev/null @@ -1,154 +0,0 @@ -import 'dart:async'; -import 'dart:math'; -import 'package:angel_framework/angel_framework.dart'; -import 'package:angel_graphql/angel_graphql.dart'; -import 'package:graphql_schema/graphql_schema.dart'; -import 'package:graphql_server/graphql_server.dart'; -import 'package:graphql_server/mirrors.dart'; -import 'src/models/models.dart'; - -Future configureServer(Angel app) async { - // Create standard Angel services. Note that these will also *automatically* be - // exposed via a REST API as well. - var droidService = app.use('/api/droids', MapService()); - var humansService = app.use('/api/humans', MapService()); - var starshipService = app.use('/api/starships', MapService()); - var rnd = Random(); - - // Create the GraphQL schema. - // `package:graphql_generator` has generated schemas for some of our - // classes. - - // A Hero can be either a Droid or Human; create a union type that represents this. - var heroType = GraphQLUnionType('Hero', [droidGraphQLType, humanGraphQLType]); - - // Create the query type. - // - // Use the `resolveViaServiceIndex` helper to load data directly from an - // Angel service. - var queryType = objectType( - 'StarWarsQuery', - description: 'A long time ago, in a galaxy far, far away...', - fields: [ - field( - 'droids', - listOf(droidGraphQLType.nonNullable()), - description: 'All droids in the known galaxy.', - resolve: resolveViaServiceIndex(droidService), - ), - field( - 'humans', - listOf(humanGraphQLType.nonNullable()), - description: 'All humans in the known galaxy.', - resolve: resolveViaServiceIndex(humansService), - ), - field( - 'starships', - listOf(starshipGraphQLType.nonNullable()), - description: 'All starships in the known galaxy.', - resolve: resolveViaServiceIndex(starshipService), - ), - field( - 'hero', - heroType, - description: - 'Finds a random hero within the known galaxy, whether a Droid or Human.', - inputs: [ - GraphQLFieldInput('ep', episodeGraphQLType), - ], - resolve: randomHeroResolver(droidService, humansService, rnd), - ), - ], - ); - - // Convert our object types to input objects, so that they can be passed to - // mutations. - var humanChangesType = humanGraphQLType.toInputObject('HumanChanges'); - - // Create the mutation type. - var mutationType = objectType( - 'StarWarsMutation', - fields: [ - // We'll use the `modify_human` mutation to modify a human in the database. - field( - 'modify_human', - humanGraphQLType.nonNullable(), - description: 'Modifies a human in the database.', - inputs: [ - GraphQLFieldInput('id', graphQLId.nonNullable()), - GraphQLFieldInput('data', humanChangesType.nonNullable()), - ], - resolve: resolveViaServiceModify(humansService), - ), - ], - ); - - // Finally, create the schema. - var schema = graphQLSchema( - queryType: queryType, - mutationType: mutationType, - ); - - // Next, create a GraphQL object, which will be passed to `graphQLHttp`, and - // used to mount a spec-compliant GraphQL endpoint on the server. - // - // The `mirrorsFieldResolver` is unnecessary in this case, because we are using - // `Map`s only, but if our services returned concrete Dart objects, we'd need - // this to allow GraphQL to read field values. - var graphQL = GraphQL(schema, defaultFieldResolver: mirrorsFieldResolver); - - // Mount the GraphQL endpoint. - app.all('/graphql', graphQLHttp(graphQL)); - - // In development, we'll want to mount GraphiQL, for easy management of the database. - if (!app.isProduction) { - app.get('/graphiql', graphiQL()); - } - - // Seed the database. - var leia = await humansService.create({ - 'name': 'Leia Organa', - 'appears_in': ['NEWHOPE', 'EMPIRE', 'JEDI'], - 'total_credits': 520, - }); - - var lando = await humansService.create({ - 'name': 'Lando Calrissian', - 'appears_in': ['EMPIRE', 'JEDI'], - 'total_credits': 525430, - }); - - var hanSolo = await humansService.create({ - 'name': 'Han Solo', - 'appears_in': ['NEWHOPE', 'EMPIRE', 'JEDI'], - 'total_credits': 23, - 'friends': [leia, lando], - }); - - // Luke, of course. - await humansService.create({ - 'name': 'Luke Skywalker', - 'appears_in': ['NEWHOPE', 'EMPIRE', 'JEDI'], - 'total_credits': 682, - 'friends': [leia, hanSolo, lando], - }); -} - -GraphQLFieldResolver randomHeroResolver( - Service droidService, Service humansService, Random rnd) { - return (_, args) async { - var allHeroes = []; - var allDroids = await droidService.index(); - var allHumans = await humansService.index(); - allHeroes..addAll(allDroids)..addAll(allHumans); - - // Ignore the annoying cast here, hopefully Dart 2 fixes cases like this - allHeroes = allHeroes - .where((m) => - !args.containsKey('ep') || - (m['appears_in'].contains(args['ep']) as bool)) - .toList(); - - return allHeroes.isEmpty ? null : allHeroes[rnd.nextInt(allHeroes.length)]; - }; -} diff --git a/packages/graphql/example_star_wars/mono_pkg.yaml b/packages/graphql/example_star_wars/mono_pkg.yaml deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/graphql/example_star_wars/pubspec.yaml b/packages/graphql/example_star_wars/pubspec.yaml deleted file mode 100644 index 33f86dbf..00000000 --- a/packages/graphql/example_star_wars/pubspec.yaml +++ /dev/null @@ -1,27 +0,0 @@ -name: star_wars -publish_to: none -environment: - sdk: ">=2.10.0 <2.12.0" -dependencies: - #angel_file_service: ^1.0.0 - angel_graphql: - path: ../angel_graphql - angel_hot: #^2.0.0-alpha - path: ../../hot - angel_serialize: #^2.0.0 - path: ../../serialize/angel_serialize - io: ^0.3.2 -dev_dependencies: - angel_serialize_generator: #^2.0.0 - path: ../../serialize/angel_serialize_generator - build_runner: ^1.0.0 - graphql_generator: - path: ../graphql_generator -dependency_overrides: - graphql_parser: - path: ../graphql_parser - graphql_schema: - path: ../graphql_schema - graphql_server: - path: ../graphql_server - \ No newline at end of file diff --git a/packages/graphql/graphql.iml b/packages/graphql/graphql.iml deleted file mode 100644 index ba9c74b6..00000000 --- a/packages/graphql/graphql.iml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/packages/graphql/graphql_generator/.gitignore b/packages/graphql/graphql_generator/.gitignore deleted file mode 100644 index 26517d3b..00000000 --- a/packages/graphql/graphql_generator/.gitignore +++ /dev/null @@ -1,93 +0,0 @@ -# See https://www.dartlang.org/tools/private-files.html - -# Files and directories created by pub -.buildlog -.packages -.project -.pub/ -.scripts-bin/ -build/ -**/packages/ - -# Files created by dart2js -# (Most Dart developers will use pub build to compile Dart, use/modify these -# rules if you intend to use dart2js directly -# Convention is to use extension '.dart.js' for Dart compiled to Javascript to -# differentiate from explicit Javascript files) -*.dart.js -*.part.js -*.js.deps -*.js.map -*.info.json - -# Directory created by dartdoc -doc/api/ - -# Don't commit pubspec lock file -# (Library packages only! Remove pattern if developing an application package) -pubspec.lock -### Dart template -# See https://www.dartlang.org/tools/private-files.html - -# Files and directories created by pub - -# SDK 1.20 and later (no longer creates packages directories) - -# Older SDK versions -# (Include if the minimum SDK version specified in pubsepc.yaml is earlier than 1.20) - - -# Files created by dart2js -# (Most Dart developers will use pub build to compile Dart, use/modify these -# rules if you intend to use dart2js directly -# Convention is to use extension '.dart.js' for Dart compiled to Javascript to -# differentiate from explicit Javascript files) - -# Directory created by dartdoc - -# Don't commit pubspec lock file -# (Library packages only! Remove pattern if developing an application package) -### JetBrains template -# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm -# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 - -# User-specific stuff: -../.idea/workspace.xml -.idea/**/tasks.xml -.idea/dictionaries - -# Sensitive or high-churn files: -.idea/**/dataSources/ -.idea/**/dataSources.ids -.idea/**/dataSources.xml -.idea/**/dataSources.local.xml -.idea/**/sqlDataSources.xml -.idea/**/dynamic.xml -.idea/**/uiDesigner.xml - -# Gradle: -.idea/**/gradle.xml -.idea/**/libraries - -# Mongo Explorer plugin: -.idea/**/mongoSettings.xml - -## File-based project format: -*.iws - -## Plugin-specific files: - -# IntelliJ -/out/ - -# mpeltonen/sbt-idea plugin -.idea_modules/ - -# JIRA plugin -atlassian-ide-plugin.xml - -# Crashlytics plugin (for Android Studio and IntelliJ) -com_crashlytics_export_strings.xml -crashlytics.properties -crashlytics-build.properties -fabric.properties diff --git a/packages/graphql/graphql_generator/CHANGELOG.md b/packages/graphql/graphql_generator/CHANGELOG.md deleted file mode 100644 index 2fc75072..00000000 --- a/packages/graphql/graphql_generator/CHANGELOG.md +++ /dev/null @@ -1,9 +0,0 @@ -# 1.0.0+1 -* Replace `snakeCase` with `camelCase`. - -# 1.0.0 -* Apply `package:pedantic`. - -# 1.0.0-rc.1 -* Add `CHANGELOG.md`, `example/main.dart`. -* Add documentation to `README.md`. \ No newline at end of file diff --git a/packages/graphql/graphql_generator/LICENSE b/packages/graphql/graphql_generator/LICENSE deleted file mode 100644 index 89074fd3..00000000 --- a/packages/graphql/graphql_generator/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2017 The Angel Framework - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/packages/graphql/graphql_generator/README.md b/packages/graphql/graphql_generator/README.md deleted file mode 100644 index fc990e3c..00000000 --- a/packages/graphql/graphql_generator/README.md +++ /dev/null @@ -1,52 +0,0 @@ -# graphql_generator -[![Pub](https://img.shields.io/pub/v/graphql_generator.svg)](https://pub.dartlang.org/packages/graphql_generator) -[![build status](https://travis-ci.org/angel-dart/graphql.svg)](https://travis-ci.org/angel-dart/graphql) - -Generates `package:graphql_schema` schemas for -annotated class. - -Replaces `convertDartType` from `package:graphql_server`. - -## Usage -Usage is very simple. You just need a `@graphQLClass` or `@GraphQLClass()` annotation -on any class you want to generate an object type for. - -Individual fields can have a `@GraphQLDocumentation()` annotation, to provide information -like descriptions, deprecation reasons, etc. - -```dart -@graphQLClass -@GraphQLDocumentation(description: 'Todo object type') -class Todo { - String text; - - /// Whether this item is complete - bool isComplete; -} - -void main() { - print(todoGraphQLType.fields.map((f) => f.name)); -} -``` - -The following is generated (as of April 18th, 2019): - -```dart -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'main.dart'; - -// ************************************************************************** -// _GraphQLGenerator -// ************************************************************************** - -/// Auto-generated from [Todo]. -final GraphQLObjectType todoGraphQLType = objectType('Todo', - isInterface: false, - description: 'Todo object type', - interfaces: [], - fields: [ - field('text', graphQLString), - field('isComplete', graphQLBoolean, description: 'Whether this item is complete') - ]); -``` diff --git a/packages/graphql/graphql_generator/analysis_options.yaml b/packages/graphql/graphql_generator/analysis_options.yaml deleted file mode 100644 index c230cee7..00000000 --- a/packages/graphql/graphql_generator/analysis_options.yaml +++ /dev/null @@ -1,4 +0,0 @@ -include: package:pedantic/analysis_options.yaml -analyzer: - strong-mode: - implicit-casts: false \ No newline at end of file diff --git a/packages/graphql/graphql_generator/build.yaml b/packages/graphql/graphql_generator/build.yaml deleted file mode 100644 index 7b7c514f..00000000 --- a/packages/graphql/graphql_generator/build.yaml +++ /dev/null @@ -1,14 +0,0 @@ -builders: - graphql: - import: "package:graphql_generator/graphql_generator.dart" - builder_factories: - - graphQLBuilder - auto_apply: root_package - build_to: cache - build_extensions: - .dart: - - graphql_generator.g.part - required_inputs: - - angel_serialize.g.part - applies_builders: - - source_gen|combining_builder \ No newline at end of file diff --git a/packages/graphql/graphql_generator/example/main.dart b/packages/graphql/graphql_generator/example/main.dart deleted file mode 100644 index a2ecbe35..00000000 --- a/packages/graphql/graphql_generator/example/main.dart +++ /dev/null @@ -1,14 +0,0 @@ -import 'package:graphql_schema/graphql_schema.dart'; -part 'main.g.dart'; - -@graphQLClass -class TodoItem { - String text; - - @GraphQLDocumentation(description: 'Whether this item is complete.') - bool isComplete; -} - -void main() { - print(todoItemGraphQLType.fields.map((f) => f.name)); -} diff --git a/packages/graphql/graphql_generator/example/main.g.dart b/packages/graphql/graphql_generator/example/main.g.dart deleted file mode 100644 index f9a9ebcb..00000000 --- a/packages/graphql/graphql_generator/example/main.g.dart +++ /dev/null @@ -1,16 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'main.dart'; - -// ************************************************************************** -// _GraphQLGenerator -// ************************************************************************** - -/// Auto-generated from [TodoItem]. -final GraphQLObjectType todoItemGraphQLType = objectType('TodoItem', - isInterface: false, - interfaces: [], - fields: [ - field('text', graphQLString), - field('isComplete', graphQLBoolean) - ]); diff --git a/packages/graphql/graphql_generator/lib/graphql_generator.dart b/packages/graphql/graphql_generator/lib/graphql_generator.dart deleted file mode 100644 index 949aab51..00000000 --- a/packages/graphql/graphql_generator/lib/graphql_generator.dart +++ /dev/null @@ -1,233 +0,0 @@ -import 'dart:async'; -import 'dart:mirrors'; -import 'package:analyzer/dart/element/element.dart'; -import 'package:analyzer/dart/element/type.dart'; -import 'package:angel_model/angel_model.dart'; -import 'package:angel_serialize_generator/build_context.dart'; -import 'package:angel_serialize_generator/context.dart'; -import 'package:build/build.dart'; -import 'package:code_builder/code_builder.dart'; -import 'package:graphql_schema/graphql_schema.dart'; -import 'package:recase/recase.dart'; -import 'package:source_gen/source_gen.dart'; - -/// Generates GraphQL schemas, statically. -Builder graphQLBuilder(_) { - return SharedPartBuilder([_GraphQLGenerator()], 'graphql_generator'); -} - -var _docComment = RegExp(r'^/// ', multiLine: true); -var _graphQLDoc = TypeChecker.fromRuntime(GraphQLDocumentation); -var _graphQLClassTypeChecker = TypeChecker.fromRuntime(GraphQLClass); - -class _GraphQLGenerator extends GeneratorForAnnotation { - @override - Future generateForAnnotatedElement( - Element element, ConstantReader annotation, BuildStep buildStep) async { - if (element is ClassElement) { - var ctx = element.isEnum - ? null - : await buildContext( - element, - annotation, - buildStep, - buildStep.resolver, - serializableTypeChecker.hasAnnotationOf(element)); - var lib = buildSchemaLibrary(element, ctx, annotation); - return lib.accept(DartEmitter()).toString(); - } else { - throw UnsupportedError('@GraphQLClass() is only supported on classes.'); - } - } - - bool isInterface(ClassElement clazz) { - return clazz.isAbstract && !serializableTypeChecker.hasAnnotationOf(clazz); - } - - bool _isGraphQLClass(InterfaceType clazz) { - var search = clazz; - - while (search != null) { - if (_graphQLClassTypeChecker.hasAnnotationOf(search.element)) return true; - search = search.superclass; - } - - return false; - } - - Expression _inferType(String className, String name, DartType type) { - // Firstly, check if it's a GraphQL class. - if (type is InterfaceType && _isGraphQLClass(type)) { - var c = type; - var name = serializableTypeChecker.hasAnnotationOf(c.element) && - c.name.startsWith('_') - ? c.name.substring(1) - : c.name; - var rc = ReCase(name); - return refer('${rc.camelCase}GraphQLType'); - } - - // Next, check if this is the "id" field of a `Model`. - if (TypeChecker.fromRuntime(Model).isAssignableFromType(type) && - name == 'id') { - return refer('graphQLId'); - } - - var primitive = { - String: 'graphQLString', - int: 'graphQLInt', - double: 'graphQLFloat', - bool: 'graphQLBoolean', - DateTime: 'graphQLDate' - }; - - // Check to see if it's a primitive type. - for (var entry in primitive.entries) { - if (TypeChecker.fromRuntime(entry.key).isAssignableFromType(type)) { - return refer(entry.value); - } - } - - // Next, check to see if it's a List. - if (type is InterfaceType && - type.typeArguments.isNotEmpty && - TypeChecker.fromRuntime(Iterable).isAssignableFromType(type)) { - var arg = type.typeArguments[0]; - var inner = _inferType(className, name, arg); - return refer('listOf').call([inner]); - } - - // Nothing else is allowed. - throw 'Cannot infer the GraphQL type for field $className.$name (type=$type).'; - } - - void _applyDescription( - Map named, Element element, String docComment) { - String docString = docComment; - - if (docString == null && _graphQLDoc.hasAnnotationOf(element)) { - var ann = _graphQLDoc.firstAnnotationOf(element); - var cr = ConstantReader(ann); - docString = cr.peek('description')?.stringValue; - } - - if (docString != null) { - named['description'] = literalString( - docString.replaceAll(_docComment, '').replaceAll('\n', '\\n')); - } - } - - Library buildSchemaLibrary( - ClassElement clazz, BuildContext ctx, ConstantReader ann) { - return Library((b) { - // Generate a top-level xGraphQLType object - - if (clazz.isEnum) { - b.body.add(Field((b) { - // enumTypeFromStrings(String name, List values, {String description} - var args = [literalString(clazz.name)]; - var values = - clazz.fields.where((f) => f.isEnumConstant).map((f) => f.name); - var named = {}; - _applyDescription(named, clazz, clazz.documentationComment); - args.add(literalConstList(values.map(literalString).toList())); - - b - ..name = ReCase(clazz.name).camelCase + 'GraphQLType' - ..docs.add('/// Auto-generated from [${clazz.name}].') - ..type = TypeReference((b) => b - ..symbol = 'GraphQLEnumType' - ..types.add(refer('String'))) - ..modifier = FieldModifier.final$ - ..assignment = refer('enumTypeFromStrings').call(args, named).code; - })); - } else { - b.body.add(Field((b) { - var args = [literalString(ctx.modelClassName)]; - var named = { - 'isInterface': literalBool(isInterface(clazz)) - }; - - // Add documentation - _applyDescription(named, clazz, clazz.documentationComment); - - // Add interfaces - var interfaces = clazz.interfaces.where(_isGraphQLClass).map((c) { - var name = serializableTypeChecker.hasAnnotationOf(c.element) && - c.name.startsWith('_') - ? c.name.substring(1) - : c.name; - var rc = ReCase(name); - return refer('${rc.camelCase}GraphQLType'); - }); - named['interfaces'] = literalList(interfaces); - - // Add fields - var ctxFields = ctx.fields.toList(); - - // Also incorporate parent fields. - var search = clazz.type; - while (search != null && - !TypeChecker.fromRuntime(Object).isExactlyType(search)) { - for (var field in search.element.fields) { - if (!ctxFields.any((f) => f.name == field.name)) { - ctxFields.add(field); - } - } - - search = search.superclass; - } - - var fields = []; - for (var field in ctxFields) { - var named = {}; - var originalField = clazz.fields - .firstWhere((f) => f.name == field.name, orElse: () => null); - - // Check if it is deprecated. - var depEl = originalField?.getter ?? originalField ?? field; - var depAnn = - TypeChecker.fromRuntime(Deprecated).firstAnnotationOf(depEl); - if (depAnn != null) { - var dep = ConstantReader(depAnn); - var reason = dep.peek('messages')?.stringValue ?? - dep.peek('expires')?.stringValue ?? - 'Expires: ${deprecated.message}.'; - named['deprecationReason'] = literalString(reason); - } - - // Description finder... - _applyDescription( - named, - originalField?.getter ?? originalField ?? field, - originalField?.getter?.documentationComment ?? - originalField?.documentationComment); - - // Pick the type. - var doc = _graphQLDoc.firstAnnotationOf(depEl); - Expression type; - if (doc != null) { - var cr = ConstantReader(doc); - var typeName = cr.peek('typeName')?.symbolValue; - if (typeName != null) - type = refer(MirrorSystem.getName(typeName)); - } - - fields.add(refer('field').call([ - literalString(ctx.resolveFieldName(field.name)), - type ??= _inferType(clazz.name, field.name, field.type) - ], named)); - } - named['fields'] = literalList(fields); - - b - ..name = ctx.modelClassNameRecase.camelCase + 'GraphQLType' - ..docs.add('/// Auto-generated from [${ctx.modelClassName}].') - ..type = refer('GraphQLObjectType') - ..modifier = FieldModifier.final$ - ..assignment = refer('objectType').call(args, named).code; - })); - } - }); - } -} diff --git a/packages/graphql/graphql_generator/mono_pkg.yaml b/packages/graphql/graphql_generator/mono_pkg.yaml deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/graphql/graphql_generator/pubspec.yaml b/packages/graphql/graphql_generator/pubspec.yaml deleted file mode 100644 index 5131e585..00000000 --- a/packages/graphql/graphql_generator/pubspec.yaml +++ /dev/null @@ -1,23 +0,0 @@ -name: graphql_generator -version: 1.0.0+1 -description: Generates GraphQL schemas from Dart classes, for use with pkg:graphql_server. -author: Tobe O -homepage: https://github.com/angel-dart/graphql -environment: - sdk: ">=2.10.0 <2.12.0" -dependencies: - analyzer: ">=0.27.1 <2.0.0" - angel_model: #^1.0.0 - path: ../../model - angel_serialize_generator: #^2.0.0 - path: ../../serialize/angel_serialize_generator - build: ^1.0.0 - build_config: ^0.3.0 - code_builder: ^3.0.0 - graphql_schema: #^1.0.2 - path: ../graphql_schema - recase: ^2.0.0 - source_gen: ^0.9.4 -dev_dependencies: - build_runner: ^1.0.0 - pedantic: ^1.0.0 \ No newline at end of file diff --git a/packages/graphql/graphql_parser/.gitignore b/packages/graphql/graphql_parser/.gitignore deleted file mode 100644 index 40339bc6..00000000 --- a/packages/graphql/graphql_parser/.gitignore +++ /dev/null @@ -1,95 +0,0 @@ -# See https://www.dartlang.org/tools/private-files.html - -# Files and directories created by pub -.buildlog -.packages -.project -.pub/ -.scripts-bin/ -build/ -**/packages/ - -# Files created by dart2js -# (Most Dart developers will use pub build to compile Dart, use/modify these -# rules if you intend to use dart2js directly -# Convention is to use extension '.dart.js' for Dart compiled to Javascript to -# differentiate from explicit Javascript files) -*.dart.js -*.part.js -*.js.deps -*.js.map -*.info.json - -# Directory created by dartdoc -doc/api/ - -# Don't commit pubspec lock file -# (Library packages only! Remove pattern if developing an application package) -pubspec.lock -### Dart template -# See https://www.dartlang.org/tools/private-files.html - -# Files and directories created by pub - -# SDK 1.20 and later (no longer creates packages directories) - -# Older SDK versions -# (Include if the minimum SDK version specified in pubsepc.yaml is earlier than 1.20) - - -# Files created by dart2js -# (Most Dart developers will use pub build to compile Dart, use/modify these -# rules if you intend to use dart2js directly -# Convention is to use extension '.dart.js' for Dart compiled to Javascript to -# differentiate from explicit Javascript files) - -# Directory created by dartdoc - -# Don't commit pubspec lock file -# (Library packages only! Remove pattern if developing an application package) -### JetBrains template -# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm -# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 - -# User-specific stuff: -../.idea/workspace.xml -.idea/**/tasks.xml -.idea/dictionaries - -# Sensitive or high-churn files: -.idea/**/dataSources/ -.idea/**/dataSources.ids -.idea/**/dataSources.xml -.idea/**/dataSources.local.xml -.idea/**/sqlDataSources.xml -.idea/**/dynamic.xml -.idea/**/uiDesigner.xml - -# Gradle: -.idea/**/gradle.xml -.idea/**/libraries - -# Mongo Explorer plugin: -.idea/**/mongoSettings.xml - -## File-based project format: -*.iws - -## Plugin-specific files: - -# IntelliJ -/out/ - -# mpeltonen/sbt-idea plugin -.idea_modules/ - -# JIRA plugin -atlassian-ide-plugin.xml - -# Crashlytics plugin (for Android Studio and IntelliJ) -com_crashlytics_export_strings.xml -crashlytics.properties -crashlytics-build.properties -fabric.properties - -.dart_tool \ No newline at end of file diff --git a/packages/graphql/graphql_parser/CHANGELOG.md b/packages/graphql/graphql_parser/CHANGELOG.md deleted file mode 100644 index 7efd884c..00000000 --- a/packages/graphql/graphql_parser/CHANGELOG.md +++ /dev/null @@ -1,28 +0,0 @@ -# 1.2.0 -* Combine `ValueContext` and `VariableContext` into a single `InputValueContext` supertype. - * Add `T computeValue(Map variables);` - * Resolve [#23](https://github.com/angel-dart/graphql/issues/23). -* Deprecate old `ValueOrVariable` class, and parser/AST methods related to it. - -# 1.1.4 -* Fix broken int variable parsing - https://github.com/angel-dart/graphql/pull/32 - -# 1.1.3 -* Add `Parser.nextName`, and remove all formerly-reserved words from the lexer. -Resolves [#19](https://github.com/angel-dart/graphql/issues/19). - -# 1.1.2 -* Parse the `subscription` keyword. - -# 1.1.1 -* Pubspec updates for Dart 2. - -# 1.1.0 -* Removed `GraphQLVisitor`. -* Enable parsing operations without an explicit -name. -* Parse `null`. -* Completely ignore commas. -* Ignore Unicode BOM, as per the spec. -* Parse object values. -* Parse enum values. diff --git a/packages/graphql/graphql_parser/LICENSE b/packages/graphql/graphql_parser/LICENSE deleted file mode 100644 index 89074fd3..00000000 --- a/packages/graphql/graphql_parser/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2017 The Angel Framework - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/packages/graphql/graphql_parser/README.md b/packages/graphql/graphql_parser/README.md deleted file mode 100644 index a91d3e49..00000000 --- a/packages/graphql/graphql_parser/README.md +++ /dev/null @@ -1,47 +0,0 @@ -# graphql_parser -[![Pub](https://img.shields.io/pub/v/graphql_parser.svg)](https://pub.dartlang.org/packages/graphql_parser) -[![build status](https://travis-ci.org/angel-dart/graphql.svg)](https://travis-ci.org/angel-dart/graphql) - -Parses GraphQL queries and schemas. - -*This library is merely a parser/visitor*. Any sort of actual GraphQL API functionality must be implemented by you, -or by a third-party package. - -[Angel framework](https://angel-dart.github.io) -users should consider -[`package:angel_graphql`](https://pub.dartlang.org/packages/angel_graphql) -as a dead-simple way to add GraphQL functionality to their servers. - -# Installation -Add `graphql_parser` as a dependency in your `pubspec.yaml` file: - -```yaml -dependencies: - graphql_parser: ^1.0.0 -``` - -# Usage -The AST featured in this library was originally directly based off this ANTLR4 grammar created by Joseph T. McBride: -https://github.com/antlr/grammars-v4/blob/master/graphql/GraphQL.g4 - -It has since been updated to reflect upon the grammar in the official GraphQL -specification ( -[June 2018](https://facebook.github.io/graphql/June2018/)). - -```dart -import 'package:graphql_parser/graphql_parser.dart'; - -doSomething(String text) { - var tokens = scan(text); - var parser = Parser(tokens); - - if (parser.errors.isNotEmpty) { - // Handle errors... - } - - // Parse the GraphQL document using recursive descent - var doc = parser.parseDocument(); - - // Do something with the parsed GraphQL document... -} -``` diff --git a/packages/graphql/graphql_parser/analysis_options.yaml b/packages/graphql/graphql_parser/analysis_options.yaml deleted file mode 100644 index c230cee7..00000000 --- a/packages/graphql/graphql_parser/analysis_options.yaml +++ /dev/null @@ -1,4 +0,0 @@ -include: package:pedantic/analysis_options.yaml -analyzer: - strong-mode: - implicit-casts: false \ No newline at end of file diff --git a/packages/graphql/graphql_parser/example/example.dart b/packages/graphql/graphql_parser/example/example.dart deleted file mode 100644 index aabba873..00000000 --- a/packages/graphql/graphql_parser/example/example.dart +++ /dev/null @@ -1,26 +0,0 @@ -import 'package:graphql_parser/graphql_parser.dart'; - -final String text = ''' -{ - project(name: "GraphQL") { - tagline - } -} - ''' - .trim(); - -main() { - var tokens = scan(text); - var parser = Parser(tokens); - var doc = parser.parseDocument(); - - var operation = doc.definitions.first as OperationDefinitionContext; - - var projectField = operation.selectionSet.selections.first.field; - print(projectField.fieldName.name); // project - print(projectField.arguments.first.name); // name - print(projectField.arguments.first.value); // GraphQL - - var taglineField = projectField.selectionSet.selections.first.field; - print(taglineField.fieldName.name); // tagline -} diff --git a/packages/graphql/graphql_parser/graphql_parser.iml b/packages/graphql/graphql_parser/graphql_parser.iml deleted file mode 100644 index ae9af975..00000000 --- a/packages/graphql/graphql_parser/graphql_parser.iml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/packages/graphql/graphql_parser/lib/graphql_parser.dart b/packages/graphql/graphql_parser/lib/graphql_parser.dart deleted file mode 100644 index 864f124c..00000000 --- a/packages/graphql/graphql_parser/lib/graphql_parser.dart +++ /dev/null @@ -1,2 +0,0 @@ -export 'src/language/ast/ast.dart'; -export 'src/language/language.dart'; diff --git a/packages/graphql/graphql_parser/lib/src/language/ast/alias.dart b/packages/graphql/graphql_parser/lib/src/language/ast/alias.dart deleted file mode 100644 index 1c986bd2..00000000 --- a/packages/graphql/graphql_parser/lib/src/language/ast/alias.dart +++ /dev/null @@ -1,33 +0,0 @@ -import 'package:source_span/source_span.dart'; -import '../token.dart'; -import 'node.dart'; - -/// An alternate name for a field within a [SelectionSet]. -class AliasContext extends Node { - /// The source tokens. - final Token nameToken1, colonToken, nameToken2; - - AliasContext(this.nameToken1, this.colonToken, this.nameToken2); - - /// Use [nameToken1] instead. - @deprecated - Token get NAME1 => nameToken1; - - /// Use [colonToken] instead. - @deprecated - Token get COLON => colonToken; - - /// Use [nameToken2] instead. - @deprecated - Token get NAME2 => nameToken2; - - /// The aliased name of the value. - String get alias => nameToken1.text; - - /// The actual name of the value. - String get name => nameToken2.text; - - @override - FileSpan get span => - nameToken1.span.expand(colonToken.span).expand(nameToken2.span); -} diff --git a/packages/graphql/graphql_parser/lib/src/language/ast/argument.dart b/packages/graphql/graphql_parser/lib/src/language/ast/argument.dart deleted file mode 100644 index 00382da8..00000000 --- a/packages/graphql/graphql_parser/lib/src/language/ast/argument.dart +++ /dev/null @@ -1,34 +0,0 @@ -import 'package:source_span/source_span.dart'; -import '../token.dart'; -import 'node.dart'; -import 'input_value.dart'; - -/// An argument passed to a [FieldContext]. -class ArgumentContext extends Node { - /// The source tokens. - final Token nameToken, colonToken; - - /// The value of the argument. - final InputValueContext value; - - ArgumentContext(this.nameToken, this.colonToken, this.value); - - /// Use [value] instead. - @deprecated - InputValueContext get valueOrVariable => value; - - /// Use [nameToken] instead. - @deprecated - Token get NAME => nameToken; - - /// Use [colonToken] instead. - @deprecated - Token get COLON => colonToken; - - /// The name of the argument, as a [String]. - String get name => nameToken.text; - - @override - FileSpan get span => - nameToken.span.expand(colonToken.span).expand(value.span); -} diff --git a/packages/graphql/graphql_parser/lib/src/language/ast/array_value.dart b/packages/graphql/graphql_parser/lib/src/language/ast/array_value.dart deleted file mode 100644 index 51afb3df..00000000 --- a/packages/graphql/graphql_parser/lib/src/language/ast/array_value.dart +++ /dev/null @@ -1,34 +0,0 @@ -import 'package:source_span/source_span.dart'; -import '../token.dart'; -import 'input_value.dart'; - -/// A GraphQL list value literal. -class ListValueContext extends InputValueContext { - /// The source tokens. - final Token lBracketToken, rBracketToken; - - /// The child values. - final List values = []; - - ListValueContext(this.lBracketToken, this.rBracketToken); - - /// Use [lBracketToken] instead. - @deprecated - Token get LBRACKET => lBracketToken; - - /// Use [rBracketToken] instead. - @deprecated - Token get RBRACKET => rBracketToken; - - @override - FileSpan get span { - var out = - values.fold(lBracketToken.span, (o, v) => o.expand(v.span)); - return out.expand(rBracketToken.span); - } - - @override - computeValue(Map variables) { - return values.map((v) => v.computeValue(variables)).toList(); - } -} diff --git a/packages/graphql/graphql_parser/lib/src/language/ast/ast.dart b/packages/graphql/graphql_parser/lib/src/language/ast/ast.dart deleted file mode 100644 index a274ade4..00000000 --- a/packages/graphql/graphql_parser/lib/src/language/ast/ast.dart +++ /dev/null @@ -1,31 +0,0 @@ -library graphql_parser.language.ast; - -export 'alias.dart'; -export 'array_value.dart'; -export 'argument.dart'; -export 'boolean_value.dart'; -export 'default_value.dart'; -export 'definition.dart'; -export 'deprecated_value.dart'; -export 'directive.dart'; -export 'document.dart'; -export 'field.dart'; -export 'field_name.dart'; -export 'fragment_definition.dart'; -export 'fragment_spread.dart'; -export 'inline_fragment.dart'; -export 'input_value.dart'; -export 'list_type.dart'; -export 'misc_value.dart'; -export 'node.dart'; -export 'number_value.dart'; -export 'operation_definition.dart'; -export 'selection.dart'; -export 'selection_set.dart'; -export 'string_value.dart'; -export 'type.dart'; -export 'type_condition.dart'; -export 'type_name.dart'; -export 'variable.dart'; -export 'variable_definition.dart'; -export 'variable_definitions.dart'; diff --git a/packages/graphql/graphql_parser/lib/src/language/ast/boolean_value.dart b/packages/graphql/graphql_parser/lib/src/language/ast/boolean_value.dart deleted file mode 100644 index 0b8cfe8f..00000000 --- a/packages/graphql/graphql_parser/lib/src/language/ast/boolean_value.dart +++ /dev/null @@ -1,28 +0,0 @@ -import 'package:source_span/source_span.dart'; -import 'input_value.dart'; -import '../token.dart'; - -/// A GraphQL boolean value literal. -class BooleanValueContext extends InputValueContext { - bool _valueCache; - - /// The source token. - final Token booleanToken; - - BooleanValueContext(this.booleanToken) { - assert(booleanToken?.text == 'true' || booleanToken?.text == 'false'); - } - - /// The [bool] value of this literal. - bool get booleanValue => _valueCache ??= booleanToken.text == 'true'; - - /// Use [booleanToken] instead. - @deprecated - Token get BOOLEAN => booleanToken; - - @override - FileSpan get span => booleanToken.span; - - @override - bool computeValue(Map variables) => booleanValue; -} diff --git a/packages/graphql/graphql_parser/lib/src/language/ast/default_value.dart b/packages/graphql/graphql_parser/lib/src/language/ast/default_value.dart deleted file mode 100644 index d3b805b5..00000000 --- a/packages/graphql/graphql_parser/lib/src/language/ast/default_value.dart +++ /dev/null @@ -1,22 +0,0 @@ -import 'package:source_span/source_span.dart'; -import '../token.dart'; -import 'input_value.dart'; -import 'node.dart'; - -/// The default value to be passed to an [ArgumentContext]. -class DefaultValueContext extends Node { - /// The source token. - final Token equalsToken; - - /// The default value for the argument. - final InputValueContext value; - - DefaultValueContext(this.equalsToken, this.value); - - /// Use [equalsToken] instead. - @deprecated - Token get EQUALS => equalsToken; - - @override - FileSpan get span => equalsToken.span.expand(value.span); -} diff --git a/packages/graphql/graphql_parser/lib/src/language/ast/definition.dart b/packages/graphql/graphql_parser/lib/src/language/ast/definition.dart deleted file mode 100644 index d129d422..00000000 --- a/packages/graphql/graphql_parser/lib/src/language/ast/definition.dart +++ /dev/null @@ -1,13 +0,0 @@ -import 'node.dart'; - -/// The base class for top-level GraphQL definitions. -abstract class DefinitionContext extends Node {} - -/// An executable definition. -abstract class ExecutableDefinitionContext extends DefinitionContext {} - -/// An ad-hoc type system declared in GraphQL. -abstract class TypeSystemDefinitionContext extends DefinitionContext {} - -/// An extension to an existing ad-hoc type system. -abstract class TypeSystemExtensionContext extends DefinitionContext {} diff --git a/packages/graphql/graphql_parser/lib/src/language/ast/deprecated_value.dart b/packages/graphql/graphql_parser/lib/src/language/ast/deprecated_value.dart deleted file mode 100644 index 5dfca6ef..00000000 --- a/packages/graphql/graphql_parser/lib/src/language/ast/deprecated_value.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'input_value.dart'; - -/// Use [ConstantContext] instead. This class remains solely for backwards compatibility. -@deprecated -abstract class ValueContext extends InputValueContext { - /// Return a constant value. - T get value; - - @override - T computeValue(Map variables) => value; -} diff --git a/packages/graphql/graphql_parser/lib/src/language/ast/directive.dart b/packages/graphql/graphql_parser/lib/src/language/ast/directive.dart deleted file mode 100644 index 4e7200ed..00000000 --- a/packages/graphql/graphql_parser/lib/src/language/ast/directive.dart +++ /dev/null @@ -1,62 +0,0 @@ -import 'package:source_span/source_span.dart'; -import '../token.dart'; -import 'argument.dart'; -import 'input_value.dart'; -import 'node.dart'; - -/// A GraphQL directive, which may or may not have runtime semantics. -class DirectiveContext extends Node { - /// The source tokens. - final Token arrobaToken, nameToken, colonToken, lParenToken, rParenToken; - - /// The argument being passed as the directive. - final ArgumentContext argument; - - /// The (optional) value being passed with the directive. - final InputValueContext value; - - DirectiveContext(this.arrobaToken, this.nameToken, this.colonToken, - this.lParenToken, this.rParenToken, this.argument, this.value) { - assert(nameToken != null); - } - - /// Use [value] instead. - @deprecated - InputValueContext get valueOrVariable => value; - - /// Use [arrobaToken] instead. - @deprecated - Token get ARROBA => arrobaToken; - - /// Use [nameToken] instead. - @deprecated - Token get NAME => nameToken; - - /// Use [colonToken] instead. - @deprecated - Token get COLON => colonToken; - - /// Use [lParenToken] instead. - @deprecated - Token get LPAREN => lParenToken; - - /// Use [rParenToken] instead. - @deprecated - Token get RPAREN => rParenToken; - - @override - FileSpan get span { - var out = arrobaToken.span.expand(nameToken.span); - - if (colonToken != null) { - out = out.expand(colonToken.span).expand(value.span); - } else if (lParenToken != null) { - out = out - .expand(lParenToken.span) - .expand(argument.span) - .expand(rParenToken.span); - } - - return out; - } -} diff --git a/packages/graphql/graphql_parser/lib/src/language/ast/document.dart b/packages/graphql/graphql_parser/lib/src/language/ast/document.dart deleted file mode 100644 index 278d4d9c..00000000 --- a/packages/graphql/graphql_parser/lib/src/language/ast/document.dart +++ /dev/null @@ -1,17 +0,0 @@ -import 'package:source_span/source_span.dart'; -import 'definition.dart'; -import 'node.dart'; - -/// A GraphQL document. -class DocumentContext extends Node { - /// The top-level definitions in the document. - final List definitions = []; - - @override - FileSpan get span { - if (definitions.isEmpty) return null; - return definitions - .map((d) => d.span) - .reduce((a, b) => a.expand(b)); - } -} diff --git a/packages/graphql/graphql_parser/lib/src/language/ast/field.dart b/packages/graphql/graphql_parser/lib/src/language/ast/field.dart deleted file mode 100644 index 2998d822..00000000 --- a/packages/graphql/graphql_parser/lib/src/language/ast/field.dart +++ /dev/null @@ -1,39 +0,0 @@ -import 'package:source_span/source_span.dart'; -import 'argument.dart'; -import 'directive.dart'; -import 'field_name.dart'; -import 'node.dart'; -import 'selection_set.dart'; - -/// A field in a GraphQL [SelectionSet]. -class FieldContext extends Node { - /// The name of this field. - final FieldNameContext fieldName; - - /// Any arguments this field expects. - final List arguments = []; - - /// Any directives affixed to this field. - final List directives = []; - - /// The list of selections to resolve on an object. - final SelectionSetContext selectionSet; - - FieldContext(this.fieldName, [this.selectionSet]); - - @override - FileSpan get span { - if (selectionSet != null) { - return fieldName.span.expand(selectionSet.span); - } else if (directives.isNotEmpty) { - return directives.fold( - fieldName.span, (out, d) => out.expand(d.span)); - } - if (arguments.isNotEmpty) { - return arguments.fold( - fieldName.span, (out, a) => out.expand(a.span)); - } else { - return fieldName.span; - } - } -} diff --git a/packages/graphql/graphql_parser/lib/src/language/ast/field_name.dart b/packages/graphql/graphql_parser/lib/src/language/ast/field_name.dart deleted file mode 100644 index 4841d6ce..00000000 --- a/packages/graphql/graphql_parser/lib/src/language/ast/field_name.dart +++ /dev/null @@ -1,27 +0,0 @@ -import 'package:source_span/source_span.dart'; -import '../token.dart'; -import 'alias.dart'; -import 'node.dart'; - -/// The name of a GraphQL [FieldContext], which may or may not be [alias]ed. -class FieldNameContext extends Node { - /// The source token. - final Token nameToken; - - /// An (optional) alias for the field. - final AliasContext alias; - - FieldNameContext(this.nameToken, [this.alias]) { - assert(nameToken != null || alias != null); - } - - /// Use [nameToken] instead. - @deprecated - Token get NAME => nameToken; - - /// The [String] value of the [nameToken], if any. - String get name => nameToken?.text; - - @override - FileSpan get span => alias?.span ?? nameToken.span; -} diff --git a/packages/graphql/graphql_parser/lib/src/language/ast/fragment_definition.dart b/packages/graphql/graphql_parser/lib/src/language/ast/fragment_definition.dart deleted file mode 100644 index 00204bf2..00000000 --- a/packages/graphql/graphql_parser/lib/src/language/ast/fragment_definition.dart +++ /dev/null @@ -1,49 +0,0 @@ -import '../token.dart'; -import 'definition.dart'; -import 'directive.dart'; -import 'package:source_span/source_span.dart'; -import 'selection_set.dart'; -import 'type_condition.dart'; - -/// A GraphQL query fragment definition. -class FragmentDefinitionContext extends ExecutableDefinitionContext { - /// The source tokens. - final Token fragmentToken, nameToken, onToken; - - /// The type to which this fragment applies. - final TypeConditionContext typeCondition; - - /// Any directives on the fragment. - final List directives = []; - - /// The selections to apply when the [typeCondition] is met. - final SelectionSetContext selectionSet; - - /// The [String] value of the [nameToken]. - String get name => nameToken.text; - - FragmentDefinitionContext(this.fragmentToken, this.nameToken, this.onToken, - this.typeCondition, this.selectionSet); - - /// Use [fragmentToken] instead. - @deprecated - Token get FRAGMENT => fragmentToken; - - /// Use [nameToken] instead. - @deprecated - Token get NAME => nameToken; - - /// Use [onToken] instead. - @deprecated - Token get ON => onToken; - - @override - FileSpan get span { - var out = fragmentToken.span - .expand(nameToken.span) - .expand(onToken.span) - .expand(typeCondition.span); - out = directives.fold(out, (o, d) => o.expand(d.span)); - return out.expand(selectionSet.span); - } -} diff --git a/packages/graphql/graphql_parser/lib/src/language/ast/fragment_spread.dart b/packages/graphql/graphql_parser/lib/src/language/ast/fragment_spread.dart deleted file mode 100644 index 36a68383..00000000 --- a/packages/graphql/graphql_parser/lib/src/language/ast/fragment_spread.dart +++ /dev/null @@ -1,33 +0,0 @@ -import '../token.dart'; -import 'directive.dart'; -import 'node.dart'; -import 'package:source_span/source_span.dart'; - -/// A GraphQL fragment spread. -class FragmentSpreadContext extends Node { - /// The source tokens. - final Token ellipsisToken, nameToken; - - /// Any directives affixed to this fragment spread. - final List directives = []; - - FragmentSpreadContext(this.ellipsisToken, this.nameToken); - - /// The [String] value of the [nameToken]. - String get name => nameToken.text; - - /// Use [ellipsisToken] instead. - @deprecated - Token get ELLIPSIS => ellipsisToken; - - /// Use [nameToken] instead. - @deprecated - Token get NAME => nameToken; - - @override - FileSpan get span { - var out = ellipsisToken.span.expand(nameToken.span); - if (directives.isEmpty) return out; - return directives.fold(out, (o, d) => o.expand(d.span)); - } -} diff --git a/packages/graphql/graphql_parser/lib/src/language/ast/inline_fragment.dart b/packages/graphql/graphql_parser/lib/src/language/ast/inline_fragment.dart deleted file mode 100644 index d73a8080..00000000 --- a/packages/graphql/graphql_parser/lib/src/language/ast/inline_fragment.dart +++ /dev/null @@ -1,40 +0,0 @@ -import '../token.dart'; -import 'directive.dart'; -import 'node.dart'; -import 'package:source_span/source_span.dart'; -import 'selection_set.dart'; -import 'type_condition.dart'; - -/// An inline fragment, which typically appears in a [SelectionSetContext]. -class InlineFragmentContext extends Node { - /// The source tokens. - final Token ellipsisToken, onToken; - - /// The type which this fragment matches. - final TypeConditionContext typeCondition; - - /// Any directives affixed to this inline fragment. - final List directives = []; - - /// The selections applied when the [typeCondition] is met. - final SelectionSetContext selectionSet; - - InlineFragmentContext( - this.ellipsisToken, this.onToken, this.typeCondition, this.selectionSet); - - /// Use [ellipsisToken] instead. - @deprecated - Token get ELLIPSIS => ellipsisToken; - - /// Use [onToken] instead. - @deprecated - Token get ON => onToken; - - @override - FileSpan get span { - var out = - ellipsisToken.span.expand(onToken.span).expand(typeCondition.span); - out = directives.fold(out, (o, d) => o.expand(d.span)); - return out.expand(selectionSet.span); - } -} diff --git a/packages/graphql/graphql_parser/lib/src/language/ast/input_value.dart b/packages/graphql/graphql_parser/lib/src/language/ast/input_value.dart deleted file mode 100644 index 213eb5dd..00000000 --- a/packages/graphql/graphql_parser/lib/src/language/ast/input_value.dart +++ /dev/null @@ -1,7 +0,0 @@ -import 'node.dart'; - -/// Represents a value in GraphQL. -abstract class InputValueContext extends Node { - /// Computes the value, relative to some set of [variables]. - T computeValue(Map variables); -} diff --git a/packages/graphql/graphql_parser/lib/src/language/ast/list_type.dart b/packages/graphql/graphql_parser/lib/src/language/ast/list_type.dart deleted file mode 100644 index ee770e00..00000000 --- a/packages/graphql/graphql_parser/lib/src/language/ast/list_type.dart +++ /dev/null @@ -1,31 +0,0 @@ -import '../token.dart'; -import 'node.dart'; -import 'package:source_span/source_span.dart'; -import 'type.dart'; - -/// Represents a type that holds a list of another type. -class ListTypeContext extends Node { - /// The source tokens. - final Token lBracketToken, rBracketToken; - - /// The inner type. - final TypeContext innerType; - - ListTypeContext(this.lBracketToken, this.innerType, this.rBracketToken); - - /// Use [innerType] instead. - @deprecated - TypeContext get type => innerType; - - /// Use [lBracketToken] instead. - @deprecated - Token get LBRACKET => lBracketToken; - - /// Use [rBracketToken] instead. - @deprecated - Token get RBRACKET => rBracketToken; - - @override - FileSpan get span => - lBracketToken.span.expand(innerType.span).expand(rBracketToken.span); -} diff --git a/packages/graphql/graphql_parser/lib/src/language/ast/misc_value.dart b/packages/graphql/graphql_parser/lib/src/language/ast/misc_value.dart deleted file mode 100644 index 9307e4c1..00000000 --- a/packages/graphql/graphql_parser/lib/src/language/ast/misc_value.dart +++ /dev/null @@ -1,105 +0,0 @@ -import 'package:source_span/source_span.dart'; -import '../token.dart'; -import 'input_value.dart'; -import 'node.dart'; - -/// A GraphQL `null` literal. -class NullValueContext extends InputValueContext { - /// The source token. - final Token nullToken; - - NullValueContext(this.nullToken); - - /// Use [nullToken] instead. - @deprecated - Token get NULL => nullToken; - - @override - FileSpan get span => nullToken.span; - - @override - Null computeValue(Map variables) => null; -} - -/// A GraphQL enumeration literal. -class EnumValueContext extends InputValueContext { - /// The source token. - final Token nameToken; - - EnumValueContext(this.nameToken); - - /// Use [nameToken] instead. - @deprecated - Token get NAME => nameToken; - - @override - FileSpan get span => nameToken.span; - - @override - String computeValue(Map variables) => nameToken.span.text; -} - -/// A GraphQL object literal. -class ObjectValueContext extends InputValueContext> { - /// The source tokens. - final Token lBraceToken, rBraceToken; - - /// The fields in the object. - final List fields; - - ObjectValueContext(this.lBraceToken, this.fields, this.rBraceToken); - - /// Use [lBraceToken] instead. - Token get LBRACE => lBraceToken; - - /// Use [rBraceToken] instead. - @deprecated - Token get RBRACE => rBraceToken; - - @override - FileSpan get span { - var left = lBraceToken.span; - - for (var field in fields) { - left = left.expand(field.span); - } - - return left.expand(rBraceToken.span); - } - - @override - Map computeValue(Map variables) { - if (fields.isEmpty) { - return {}; - } else { - return fields.fold>({}, - (map, field) { - return map - ..[field.nameToken.text] = field.value.computeValue(variables); - }); - } - } -} - -/// A field within an [ObjectValueContext]. -class ObjectFieldContext extends Node { - /// The source tokens. - final Token nameToken, colonToken; - - /// The associated value. - final InputValueContext value; - - ObjectFieldContext(this.nameToken, this.colonToken, this.value); - - /// Use [nameToken] instead. - @deprecated - Token get NAME => nameToken; - - /// Use [colonToken] instead. - @deprecated - Token get COLON => colonToken; - - @override - FileSpan get span => - nameToken.span.expand(colonToken.span).expand(value.span); -} diff --git a/packages/graphql/graphql_parser/lib/src/language/ast/node.dart b/packages/graphql/graphql_parser/lib/src/language/ast/node.dart deleted file mode 100644 index a3ed0db8..00000000 --- a/packages/graphql/graphql_parser/lib/src/language/ast/node.dart +++ /dev/null @@ -1,5 +0,0 @@ -import 'package:source_span/source_span.dart'; - -abstract class Node { - FileSpan get span; -} diff --git a/packages/graphql/graphql_parser/lib/src/language/ast/number_value.dart b/packages/graphql/graphql_parser/lib/src/language/ast/number_value.dart deleted file mode 100644 index 733bf0e4..00000000 --- a/packages/graphql/graphql_parser/lib/src/language/ast/number_value.dart +++ /dev/null @@ -1,35 +0,0 @@ -import 'dart:math' as math; -import 'package:source_span/source_span.dart'; -import '../token.dart'; -import 'input_value.dart'; - -/// A GraphQL number literal. -class NumberValueContext extends InputValueContext { - /// The source token. - final Token numberToken; - - NumberValueContext(this.numberToken); - - /// The [num] value of the [numberToken]. - num get numberValue { - var text = numberToken.text; - if (!text.contains('E') && !text.contains('e')) { - return num.parse(text); - } else { - var split = text.split(text.contains('E') ? 'E' : 'e'); - var base = num.parse(split[0]); - var exp = num.parse(split[1]); - return base * math.pow(10, exp); - } - } - - /// Use [numberToken] instead. - @deprecated - Token get NUMBER => numberToken; - - @override - FileSpan get span => numberToken.span; - - @override - num computeValue(Map variables) => numberValue; -} diff --git a/packages/graphql/graphql_parser/lib/src/language/ast/operation_definition.dart b/packages/graphql/graphql_parser/lib/src/language/ast/operation_definition.dart deleted file mode 100644 index d614fb6b..00000000 --- a/packages/graphql/graphql_parser/lib/src/language/ast/operation_definition.dart +++ /dev/null @@ -1,59 +0,0 @@ -import 'package:source_span/source_span.dart'; -import '../token.dart'; -import 'definition.dart'; -import 'directive.dart'; -import 'selection_set.dart'; -import 'variable_definitions.dart'; - -/// An executable GraphQL operation definition. -class OperationDefinitionContext extends ExecutableDefinitionContext { - /// The source tokens. - final Token typeToken, nameToken; - - /// The variables defined in the operation. - final VariableDefinitionsContext variableDefinitions; - - /// Any directives affixed to this operation. - final List directives = []; - - /// The selections to be applied to an object resolved in this operation. - final SelectionSetContext selectionSet; - - /// Whether this operation is a `mutation`. - bool get isMutation => typeToken?.text == 'mutation'; - - /// Whether this operation is a `subscription`. - bool get isSubscription => typeToken?.text == 'subscription'; - - /// Whether this operation is a `query`. - bool get isQuery => typeToken?.text == 'query' || typeToken == null; - - /// The [String] value of the [nameToken]. - String get name => nameToken?.text; - - /// Use [nameToken] instead. - @deprecated - Token get NAME => nameToken; - - /// Use [typeToken] instead. - @deprecated - Token get TYPE => typeToken; - - OperationDefinitionContext(this.typeToken, this.nameToken, - this.variableDefinitions, this.selectionSet) { - assert(typeToken == null || - typeToken.text == 'query' || - typeToken.text == 'mutation' || - typeToken.text == 'subscription'); - } - - @override - FileSpan get span { - if (typeToken == null) return selectionSet.span; - var out = nameToken == null - ? typeToken.span - : typeToken.span.expand(nameToken.span); - out = directives.fold(out, (o, d) => o.expand(d.span)); - return out.expand(selectionSet.span); - } -} diff --git a/packages/graphql/graphql_parser/lib/src/language/ast/selection.dart b/packages/graphql/graphql_parser/lib/src/language/ast/selection.dart deleted file mode 100644 index 988ab1c7..00000000 --- a/packages/graphql/graphql_parser/lib/src/language/ast/selection.dart +++ /dev/null @@ -1,19 +0,0 @@ -import 'field.dart'; -import 'fragment_spread.dart'; -import 'inline_fragment.dart'; -import 'node.dart'; -import 'package:source_span/source_span.dart'; - -class SelectionContext extends Node { - final FieldContext field; - final FragmentSpreadContext fragmentSpread; - final InlineFragmentContext inlineFragment; - - SelectionContext(this.field, [this.fragmentSpread, this.inlineFragment]) { - assert(field != null || fragmentSpread != null || inlineFragment != null); - } - - @override - FileSpan get span => - field?.span ?? fragmentSpread?.span ?? inlineFragment?.span; -} diff --git a/packages/graphql/graphql_parser/lib/src/language/ast/selection_set.dart b/packages/graphql/graphql_parser/lib/src/language/ast/selection_set.dart deleted file mode 100644 index 4097d94e..00000000 --- a/packages/graphql/graphql_parser/lib/src/language/ast/selection_set.dart +++ /dev/null @@ -1,45 +0,0 @@ -import 'package:source_span/source_span.dart'; - -import '../token.dart'; -import 'node.dart'; -import 'selection.dart'; - -/// A set of GraphQL selections - fields, fragments, or inline fragments. -class SelectionSetContext extends Node { - /// The source tokens. - final Token lBraceToken, rBraceToken; - - /// The selections to be applied. - final List selections = []; - - SelectionSetContext(this.lBraceToken, this.rBraceToken); - - /// A synthetic [SelectionSetContext] produced from a set of [selections]. - factory SelectionSetContext.merged(List selections) = - _MergedSelectionSetContext; - - /// Use [lBraceToken] instead. - @deprecated - Token get LBRACE => lBraceToken; - - /// Use [rBraceToken] instead. - @deprecated - Token get RBRACE => rBraceToken; - - @override - FileSpan get span { - var out = selections.fold( - lBraceToken.span, (out, s) => out.expand(s.span)); - return out.expand(rBraceToken.span); - } -} - -class _MergedSelectionSetContext extends SelectionSetContext { - final List selections; - - _MergedSelectionSetContext(this.selections) : super(null, null); - - @override - FileSpan get span => - selections.map((s) => s.span).reduce((a, b) => a.expand(b)); -} diff --git a/packages/graphql/graphql_parser/lib/src/language/ast/string_value.dart b/packages/graphql/graphql_parser/lib/src/language/ast/string_value.dart deleted file mode 100644 index 29bc71af..00000000 --- a/packages/graphql/graphql_parser/lib/src/language/ast/string_value.dart +++ /dev/null @@ -1,88 +0,0 @@ -import 'package:charcode/charcode.dart'; -import 'package:source_span/source_span.dart'; - -import '../syntax_error.dart'; -import '../token.dart'; -import 'input_value.dart'; - -/// A GraphQL string value literal. -class StringValueContext extends InputValueContext { - /// The source token. - final Token stringToken; - - /// Whether this is a block string. - final bool isBlockString; - - StringValueContext(this.stringToken, {this.isBlockString = false}); - - @override - FileSpan get span => stringToken.span; - - /// Use [stringToken] instead. - @deprecated - Token get STRING => stringToken; - - /// The [String] value of the [stringToken]. - String get stringValue { - String text; - - if (!isBlockString) { - text = stringToken.text.substring(1, stringToken.text.length - 1); - } else { - text = stringToken.text.substring(3, stringToken.text.length - 3).trim(); - } - - var codeUnits = text.codeUnits; - var buf = StringBuffer(); - - for (int i = 0; i < codeUnits.length; i++) { - var ch = codeUnits[i]; - - if (ch == $backslash) { - if (i < codeUnits.length - 5 && codeUnits[i + 1] == $u) { - var c1 = codeUnits[i += 2], - c2 = codeUnits[++i], - c3 = codeUnits[++i], - c4 = codeUnits[++i]; - var hexString = String.fromCharCodes([c1, c2, c3, c4]); - var hexNumber = int.parse(hexString, radix: 16); - buf.write(String.fromCharCode(hexNumber)); - continue; - } - - if (i < codeUnits.length - 1) { - var next = codeUnits[++i]; - - switch (next) { - case $b: - buf.write('\b'); - break; - case $f: - buf.write('\f'); - break; - case $n: - buf.writeCharCode($lf); - break; - case $r: - buf.writeCharCode($cr); - break; - case $t: - buf.writeCharCode($tab); - break; - default: - buf.writeCharCode(next); - } - } else { - throw SyntaxError('Unexpected "\\" in string literal.', span); - } - } else { - buf.writeCharCode(ch); - } - } - - return buf.toString(); - } - - @override - String computeValue(Map variables) => stringValue; -} diff --git a/packages/graphql/graphql_parser/lib/src/language/ast/type.dart b/packages/graphql/graphql_parser/lib/src/language/ast/type.dart deleted file mode 100644 index d82a97e3..00000000 --- a/packages/graphql/graphql_parser/lib/src/language/ast/type.dart +++ /dev/null @@ -1,34 +0,0 @@ -import 'package:source_span/source_span.dart'; -import '../token.dart'; -import 'list_type.dart'; -import 'node.dart'; -import 'type_name.dart'; - -/// A GraphQL type node. -class TypeContext extends Node { - /// A source token, present in a nullable type literal. - final Token exclamationToken; - - /// The name of the referenced type. - final TypeNameContext typeName; - - /// A list type that is being referenced. - final ListTypeContext listType; - - /// Whether the type is nullable. - bool get isNullable => exclamationToken == null; - - TypeContext(this.typeName, this.listType, [this.exclamationToken]) { - assert(typeName != null || listType != null); - } - - /// Use [exclamationToken] instead. - @deprecated - Token get EXCLAMATION => exclamationToken; - - @override - FileSpan get span { - var out = typeName?.span ?? listType.span; - return exclamationToken != null ? out.expand(exclamationToken.span) : out; - } -} diff --git a/packages/graphql/graphql_parser/lib/src/language/ast/type_condition.dart b/packages/graphql/graphql_parser/lib/src/language/ast/type_condition.dart deleted file mode 100644 index 2600fc44..00000000 --- a/packages/graphql/graphql_parser/lib/src/language/ast/type_condition.dart +++ /dev/null @@ -1,12 +0,0 @@ -import 'node.dart'; -import 'package:source_span/source_span.dart'; -import 'type_name.dart'; - -class TypeConditionContext extends Node { - final TypeNameContext typeName; - - TypeConditionContext(this.typeName); - - @override - FileSpan get span => typeName.span; -} diff --git a/packages/graphql/graphql_parser/lib/src/language/ast/type_name.dart b/packages/graphql/graphql_parser/lib/src/language/ast/type_name.dart deleted file mode 100644 index 209de19b..00000000 --- a/packages/graphql/graphql_parser/lib/src/language/ast/type_name.dart +++ /dev/null @@ -1,21 +0,0 @@ -import 'node.dart'; -import 'package:source_span/source_span.dart'; -import '../token.dart'; - -/// The name of a GraphQL type. -class TypeNameContext extends Node { - /// The source token. - final Token nameToken; - - TypeNameContext(this.nameToken); - - /// Use [nameToken] instead. - @deprecated - Token get NAME => nameToken; - - /// The [String] value of the [nameToken]. - String get name => nameToken.text; - - @override - FileSpan get span => nameToken.span; -} diff --git a/packages/graphql/graphql_parser/lib/src/language/ast/variable.dart b/packages/graphql/graphql_parser/lib/src/language/ast/variable.dart deleted file mode 100644 index 576734e4..00000000 --- a/packages/graphql/graphql_parser/lib/src/language/ast/variable.dart +++ /dev/null @@ -1,28 +0,0 @@ -import 'package:source_span/source_span.dart'; -import '../token.dart'; -import 'input_value.dart'; - -/// A variable reference in GraphQL. -class VariableContext extends InputValueContext { - /// The source tokens. - final Token dollarToken, nameToken; - - VariableContext(this.dollarToken, this.nameToken); - - /// The [String] value of the [nameToken]. - String get name => nameToken.text; - - /// Use [dollarToken] instead. - @deprecated - Token get DOLLAR => dollarToken; - - /// Use [nameToken] instead. - @deprecated - Token get NAME => nameToken; - - @override - FileSpan get span => dollarToken.span.expand(nameToken.span); - - @override - Object computeValue(Map variables) => variables[name]; -} diff --git a/packages/graphql/graphql_parser/lib/src/language/ast/variable_definition.dart b/packages/graphql/graphql_parser/lib/src/language/ast/variable_definition.dart deleted file mode 100644 index 7432798a..00000000 --- a/packages/graphql/graphql_parser/lib/src/language/ast/variable_definition.dart +++ /dev/null @@ -1,31 +0,0 @@ -import '../token.dart'; -import 'node.dart'; -import 'default_value.dart'; -import 'package:source_span/source_span.dart'; -import 'type.dart'; -import 'variable.dart'; - -/// A single variable definition. -class VariableDefinitionContext extends Node { - /// The source token. - final Token colonToken; - - /// The declared variable. - final VariableContext variable; - - /// The type of the variable. - final TypeContext type; - - /// The default value of the variable. - final DefaultValueContext defaultValue; - - VariableDefinitionContext(this.variable, this.colonToken, this.type, - [this.defaultValue]); - - /// Use [colonToken] instead. - @deprecated - Token get COLON => colonToken; - - @override - FileSpan get span => variable.span.expand(defaultValue?.span ?? type.span); -} diff --git a/packages/graphql/graphql_parser/lib/src/language/ast/variable_definitions.dart b/packages/graphql/graphql_parser/lib/src/language/ast/variable_definitions.dart deleted file mode 100644 index ddc4405f..00000000 --- a/packages/graphql/graphql_parser/lib/src/language/ast/variable_definitions.dart +++ /dev/null @@ -1,30 +0,0 @@ -import '../token.dart'; -import 'node.dart'; -import 'package:source_span/source_span.dart'; -import 'variable_definition.dart'; - -/// A set of variable definitions in a GraphQL operation. -class VariableDefinitionsContext extends Node { - /// The source tokens. - final Token lParenToken, rParenToken; - - /// The variables defined in this node. - final List variableDefinitions = []; - - VariableDefinitionsContext(this.lParenToken, this.rParenToken); - - /// Use [lParenToken] instead. - @deprecated - Token get LPAREN => lParenToken; - - /// Use [rParenToken] instead. - @deprecated - Token get RPAREN => rParenToken; - - @override - FileSpan get span { - var out = variableDefinitions.fold( - lParenToken.span, (o, v) => o.expand(v.span)); - return out.expand(rParenToken.span); - } -} diff --git a/packages/graphql/graphql_parser/lib/src/language/language.dart b/packages/graphql/graphql_parser/lib/src/language/language.dart deleted file mode 100644 index 31ec5a43..00000000 --- a/packages/graphql/graphql_parser/lib/src/language/language.dart +++ /dev/null @@ -1,7 +0,0 @@ -library graphql_parser.language; - -export 'lexer.dart'; -export 'parser.dart'; -export 'syntax_error.dart'; -export 'token.dart'; -export 'token_type.dart'; diff --git a/packages/graphql/graphql_parser/lib/src/language/lexer.dart b/packages/graphql/graphql_parser/lib/src/language/lexer.dart deleted file mode 100644 index 1d7c35fd..00000000 --- a/packages/graphql/graphql_parser/lib/src/language/lexer.dart +++ /dev/null @@ -1,75 +0,0 @@ -import 'package:string_scanner/string_scanner.dart'; - -import 'syntax_error.dart'; -import 'token.dart'; -import 'token_type.dart'; - -final RegExp _comment = RegExp(r'#[^\n]*'); -final RegExp _whitespace = RegExp('[ \t\n\r]+'); -// final RegExp _boolean = RegExp(r'true|false'); -final RegExp _number = RegExp(r'-?[0-9]+(\.[0-9]+)?(E|e(\+|-)?[0-9]+)?'); -final RegExp _string = RegExp( - r'"((\\(["\\/bfnrt]|(u[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F])))|([^"\\]))*"'); -final RegExp _blockString = RegExp(r'"""(([^"])|(\\"""))*"""'); -final RegExp _name = RegExp(r'[_A-Za-z][_0-9A-Za-z]*'); - -final Map _patterns = { - '@': TokenType.ARROBA, - ':': TokenType.COLON, - ',': TokenType.COMMA, - r'$': TokenType.DOLLAR, - '...': TokenType.ELLIPSIS, - '=': TokenType.EQUALS, - '!': TokenType.EXCLAMATION, - '{': TokenType.LBRACE, - '}': TokenType.RBRACE, - '[': TokenType.LBRACKET, - ']': TokenType.RBRACKET, - '(': TokenType.LPAREN, - ')': TokenType.RPAREN, - // 'fragment': TokenType.FRAGMENT, - // 'mutation': TokenType.MUTATION, - // 'subscription': TokenType.SUBSCRIPTION, - // 'on': TokenType.ON, - // 'query': TokenType.QUERY, - // 'null': TokenType.NULL, - // _boolean: TokenType.BOOLEAN, - _number: TokenType.NUMBER, - _string: TokenType.STRING, - _blockString: TokenType.BLOCK_STRING, - _name: TokenType.NAME -}; - -List scan(String text, {sourceUrl}) { - List out = []; - var scanner = SpanScanner(text, sourceUrl: sourceUrl); - - while (!scanner.isDone) { - List potential = []; - - if (scanner.scan(_comment) || - scanner.scan(_whitespace) || - scanner.scan(',') || - scanner.scan('\ufeff')) continue; - - for (var pattern in _patterns.keys) { - if (scanner.matches(pattern)) { - potential.add( - Token(_patterns[pattern], scanner.lastMatch[0], scanner.lastSpan)); - } - } - - if (potential.isEmpty) { - var ch = String.fromCharCode(scanner.readChar()); - throw SyntaxError("Unexpected token '$ch'.", scanner.emptySpan); - } else { - // Choose longest token - potential.sort((a, b) => b.text.length.compareTo(a.text.length)); - var chosen = potential.first; - out.add(chosen); - scanner.scan(chosen.text); - } - } - - return out; -} diff --git a/packages/graphql/graphql_parser/lib/src/language/parser.dart b/packages/graphql/graphql_parser/lib/src/language/parser.dart deleted file mode 100644 index 9ea7d33c..00000000 --- a/packages/graphql/graphql_parser/lib/src/language/parser.dart +++ /dev/null @@ -1,615 +0,0 @@ -library graphql_parser.language.parser; - -import 'ast/ast.dart'; -import 'syntax_error.dart'; -import 'token.dart'; -import 'token_type.dart'; - -class Parser { - Token _current; - int _index = -1; - - final List tokens; - final List errors = []; - - Parser(this.tokens); - - Token get current => _current; - - bool next(TokenType type, {Iterable exclude}) { - var tok = peek(); - if (tok?.type == type && exclude?.contains(tok.span.text) != true) { - _current = tokens[++_index]; - return true; - } - - return false; - } - - bool nextName(String name) { - var tok = peek(); - if (tok?.type == TokenType.NAME && tok.span.text == name) { - return next(TokenType.NAME); - } - - return false; - } - - Token peek() { - if (_index < tokens.length - 1) { - return tokens[_index + 1]; - } - - return null; - } - - Token maybe(TokenType type) => next(type) ? current : null; - - void eatCommas() { - while (next(TokenType.COMMA)) { - continue; - } - } - - DocumentContext parseDocument() { - List defs = []; - DefinitionContext def = parseDefinition(); - - while (def != null) { - defs.add(def); - def = parseDefinition(); - } - - return DocumentContext()..definitions.addAll(defs); - } - - DefinitionContext parseDefinition() => - parseOperationDefinition() ?? parseFragmentDefinition(); - - OperationDefinitionContext parseOperationDefinition() { - var selectionSet = parseSelectionSet(); - if (selectionSet != null) { - return OperationDefinitionContext(null, null, null, selectionSet); - } else { - if (nextName('mutation') || - nextName('query') || - nextName('subscription')) { - var TYPE = current; - Token NAME = next(TokenType.NAME) ? current : null; - var variables = parseVariableDefinitions(); - var dirs = parseDirectives(); - var selectionSet = parseSelectionSet(); - if (selectionSet != null) { - return OperationDefinitionContext(TYPE, NAME, variables, selectionSet) - ..directives.addAll(dirs); - } else { - errors.add(SyntaxError( - 'Missing selection set in fragment definition.', - NAME?.span ?? TYPE.span)); - return null; - } - } else { - return null; - } - } - } - - FragmentDefinitionContext parseFragmentDefinition() { - if (nextName('fragment')) { - var FRAGMENT = current; - if (next(TokenType.NAME)) { - var NAME = current; - if (nextName('on')) { - var ON = current; - var typeCondition = parseTypeCondition(); - if (typeCondition != null) { - var dirs = parseDirectives(); - var selectionSet = parseSelectionSet(); - if (selectionSet != null) { - return FragmentDefinitionContext( - FRAGMENT, NAME, ON, typeCondition, selectionSet) - ..directives.addAll(dirs); - } else { - errors.add(SyntaxError( - 'Expected selection set in fragment definition.', - typeCondition.span)); - return null; - } - } else { - errors.add(SyntaxError( - 'Expected type condition after "on" in fragment definition.', - ON.span)); - return null; - } - } else { - errors.add(SyntaxError( - 'Expected "on" after name "${NAME.text}" in fragment definition.', - NAME.span)); - return null; - } - } else { - errors.add(SyntaxError( - 'Expected name after "fragment" in fragment definition.', - FRAGMENT.span)); - return null; - } - } else { - return null; - } - } - - FragmentSpreadContext parseFragmentSpread() { - if (next(TokenType.ELLIPSIS)) { - var ELLIPSIS = current; - if (next(TokenType.NAME, exclude: ['on'])) { - var NAME = current; - return FragmentSpreadContext(ELLIPSIS, NAME) - ..directives.addAll(parseDirectives()); - } else { - _index--; - return null; - } - } else { - return null; - } - } - - InlineFragmentContext parseInlineFragment() { - if (next(TokenType.ELLIPSIS)) { - var ELLIPSIS = current; - if (nextName('on')) { - var ON = current; - var typeCondition = parseTypeCondition(); - if (typeCondition != null) { - var directives = parseDirectives(); - var selectionSet = parseSelectionSet(); - if (selectionSet != null) { - return InlineFragmentContext( - ELLIPSIS, ON, typeCondition, selectionSet) - ..directives.addAll(directives); - } else { - errors.add(SyntaxError( - 'Missing selection set in inline fragment.', - directives.isEmpty - ? typeCondition.span - : directives.last.span)); - return null; - } - } else { - errors.add(SyntaxError( - 'Missing type condition after "on" in inline fragment.', - ON.span)); - return null; - } - } else { - errors.add(SyntaxError( - 'Missing "on" after "..." in inline fragment.', ELLIPSIS.span)); - return null; - } - } else { - return null; - } - } - - SelectionSetContext parseSelectionSet() { - if (next(TokenType.LBRACE)) { - var LBRACE = current; - List selections = []; - SelectionContext selection = parseSelection(); - - while (selection != null) { - selections.add(selection); - eatCommas(); - selection = parseSelection(); - } - - eatCommas(); - if (next(TokenType.RBRACE)) { - return SelectionSetContext(LBRACE, current) - ..selections.addAll(selections); - } else { - errors.add(SyntaxError('Missing "}" after selection set.', - selections.isEmpty ? LBRACE.span : selections.last.span)); - return null; - } - } else { - return null; - } - } - - SelectionContext parseSelection() { - var field = parseField(); - if (field != null) return SelectionContext(field); - var fragmentSpread = parseFragmentSpread(); - if (fragmentSpread != null) return SelectionContext(null, fragmentSpread); - var inlineFragment = parseInlineFragment(); - if (inlineFragment != null) { - return SelectionContext(null, null, inlineFragment); - } else { - return null; - } - } - - FieldContext parseField() { - var fieldName = parseFieldName(); - if (fieldName != null) { - var args = parseArguments(); - var directives = parseDirectives(); - var selectionSet = parseSelectionSet(); - return FieldContext(fieldName, selectionSet) - ..arguments.addAll(args ?? []) - ..directives.addAll(directives); - } else { - return null; - } - } - - FieldNameContext parseFieldName() { - if (next(TokenType.NAME)) { - var NAME1 = current; - if (next(TokenType.COLON)) { - var COLON = current; - if (next(TokenType.NAME)) { - return FieldNameContext(null, AliasContext(NAME1, COLON, current)); - } else { - errors.add( - SyntaxError('Missing name after colon in alias.', COLON.span)); - return null; - } - } else { - return FieldNameContext(NAME1); - } - } else { - return null; - } - } - - VariableDefinitionsContext parseVariableDefinitions() { - if (next(TokenType.LPAREN)) { - var LPAREN = current; - List defs = []; - VariableDefinitionContext def = parseVariableDefinition(); - - while (def != null) { - defs.add(def); - eatCommas(); - def = parseVariableDefinition(); - } - - if (next(TokenType.RPAREN)) { - return VariableDefinitionsContext(LPAREN, current) - ..variableDefinitions.addAll(defs); - } else { - errors.add(SyntaxError( - 'Missing ")" after variable definitions.', LPAREN.span)); - return null; - } - } else { - return null; - } - } - - VariableDefinitionContext parseVariableDefinition() { - var variable = parseVariable(); - if (variable != null) { - if (next(TokenType.COLON)) { - var COLON = current; - var type = parseType(); - if (type != null) { - var defaultValue = parseDefaultValue(); - return VariableDefinitionContext(variable, COLON, type, defaultValue); - } else { - errors.add( - SyntaxError('Missing type in variable definition.', COLON.span)); - return null; - } - } else { - errors.add( - SyntaxError('Missing ":" in variable definition.', variable.span)); - return null; - } - } else { - return null; - } - } - - TypeContext parseType() { - var name = parseTypeName(); - if (name != null) { - return TypeContext(name, null, maybe(TokenType.EXCLAMATION)); - } else { - var listType = parseListType(); - if (listType != null) { - return TypeContext(null, listType, maybe(TokenType.EXCLAMATION)); - } else { - return null; - } - } - } - - ListTypeContext parseListType() { - if (next(TokenType.LBRACKET)) { - var LBRACKET = current; - var type = parseType(); - if (type != null) { - if (next(TokenType.RBRACKET)) { - return ListTypeContext(LBRACKET, type, current); - } else { - errors.add(SyntaxError('Missing "]" in list type.', type.span)); - return null; - } - } else { - errors.add(SyntaxError('Missing type after "[".', LBRACKET.span)); - return null; - } - } else { - return null; - } - } - - List parseDirectives() { - List out = []; - DirectiveContext d = parseDirective(); - while (d != null) { - out.add(d); - d = parseDirective(); - } - - return out; - } - - DirectiveContext parseDirective() { - if (next(TokenType.ARROBA)) { - var ARROBA = current; - if (next(TokenType.NAME)) { - var NAME = current; - - if (next(TokenType.COLON)) { - var COLON = current; - var val = parseInputValue(); - if (val != null) { - return DirectiveContext(ARROBA, NAME, COLON, null, null, null, val); - } else { - errors.add(SyntaxError( - 'Missing value or variable in directive after colon.', - COLON.span)); - return null; - } - } else if (next(TokenType.LPAREN)) { - var LPAREN = current; - var arg = parseArgument(); - if (arg != null) { - if (next(TokenType.RPAREN)) { - return DirectiveContext( - ARROBA, NAME, null, LPAREN, current, arg, null); - } else { - errors.add(SyntaxError('Missing \')\'', arg.value.span)); - return null; - } - } else { - errors.add( - SyntaxError('Missing argument in directive.', LPAREN.span)); - return null; - } - } else { - return DirectiveContext(ARROBA, NAME, null, null, null, null, null); - } - } else { - errors.add(SyntaxError('Missing name for directive.', ARROBA.span)); - return null; - } - } else { - return null; - } - } - - List parseArguments() { - if (next(TokenType.LPAREN)) { - var LPAREN = current; - List out = []; - ArgumentContext arg = parseArgument(); - - while (arg != null) { - out.add(arg); - eatCommas(); - arg = parseArgument(); - } - - if (next(TokenType.RPAREN)) { - return out; - } else { - errors.add(SyntaxError('Missing ")" in argument list.', LPAREN.span)); - return null; - } - } else { - return []; - } - } - - ArgumentContext parseArgument() { - if (next(TokenType.NAME)) { - var NAME = current; - if (next(TokenType.COLON)) { - var COLON = current; - var val = parseInputValue(); - if (val != null) { - return ArgumentContext(NAME, COLON, val); - } else { - errors.add(SyntaxError( - 'Missing value or variable in argument.', COLON.span)); - return null; - } - } else { - errors.add( - SyntaxError('Missing colon after name in argument.', NAME.span)); - return null; - } - } else { - return null; - } - } - - /// Use [parseInputValue] instead. - @deprecated - InputValueContext parseValueOrVariable() => parseInputValue(); - - VariableContext parseVariable() { - if (next(TokenType.DOLLAR)) { - var DOLLAR = current; - if (next(TokenType.NAME)) { - return VariableContext(DOLLAR, current); - } else { - errors.add(SyntaxError( - 'Missing name for variable; found a lone "\$" instead.', - DOLLAR.span)); - return null; - } - } else { - return null; - } - } - - DefaultValueContext parseDefaultValue() { - if (next(TokenType.EQUALS)) { - var EQUALS = current; - var value = parseInputValue(); - if (value != null) { - return DefaultValueContext(EQUALS, value); - } else { - errors.add(SyntaxError('Missing value after "=" sign.', EQUALS.span)); - return null; - } - } else { - return null; - } - } - - TypeConditionContext parseTypeCondition() { - var name = parseTypeName(); - if (name != null) { - return TypeConditionContext(name); - } else { - return null; - } - } - - TypeNameContext parseTypeName() { - if (next(TokenType.NAME)) { - return TypeNameContext(current); - } else { - return null; - } - } - - /// Use [parseInputValue] instead. - @deprecated - InputValueContext parseValue() => parseInputValue(); - - InputValueContext parseInputValue() { - return (parseVariable() ?? - parseNumberValue() ?? - parseStringValue() ?? - parseBooleanValue() ?? - parseNullValue() ?? - parseEnumValue() ?? - parseListValue() ?? - parseObjectValue()) as InputValueContext; - } - - StringValueContext parseStringValue() => next(TokenType.STRING) - ? StringValueContext(current) - : (next(TokenType.BLOCK_STRING) - ? StringValueContext(current, isBlockString: true) - : null); - - NumberValueContext parseNumberValue() => - next(TokenType.NUMBER) ? NumberValueContext(current) : null; - - BooleanValueContext parseBooleanValue() => - (nextName('true') || nextName('false')) - ? BooleanValueContext(current) - : null; - - EnumValueContext parseEnumValue() => - next(TokenType.NAME) ? EnumValueContext(current) : null; - - NullValueContext parseNullValue() => - nextName('null') ? NullValueContext(current) : null; - - ListValueContext parseListValue() { - if (next(TokenType.LBRACKET)) { - var LBRACKET = current; - var lastSpan = LBRACKET.span; - List values = []; - var value = parseInputValue(); - - while (value != null) { - lastSpan = value.span; - values.add(value); - eatCommas(); - value = parseInputValue(); - } - - eatCommas(); - if (next(TokenType.RBRACKET)) { - return ListValueContext(LBRACKET, current)..values.addAll(values); - } else { - errors.add(SyntaxError('Unterminated list literal.', lastSpan)); - return null; - } - } else { - return null; - } - } - - ObjectValueContext parseObjectValue() { - if (next(TokenType.LBRACE)) { - var LBRACE = current; - var lastSpan = LBRACE.span; - var fields = []; - var field = parseObjectField(); - - while (field != null) { - fields.add(field); - lastSpan = field.span; - eatCommas(); - field = parseObjectField(); - } - - eatCommas(); - - if (next(TokenType.RBRACE)) { - return ObjectValueContext(LBRACE, fields, current); - } else { - errors.add(SyntaxError('Unterminated object literal.', lastSpan)); - return null; - } - } else { - return null; - } - } - - ObjectFieldContext parseObjectField() { - if (next(TokenType.NAME)) { - var NAME = current; - - if (next(TokenType.COLON)) { - var COLON = current; - var value = parseInputValue(); - - if (value != null) { - return ObjectFieldContext(NAME, COLON, value); - } else { - errors.add(SyntaxError('Missing value after ":".', COLON.span)); - return null; - } - } else { - errors.add(SyntaxError( - 'Missing ":" after name "${NAME.span.text}".', NAME.span)); - return null; - } - } else { - return null; - } - } -} diff --git a/packages/graphql/graphql_parser/lib/src/language/syntax_error.dart b/packages/graphql/graphql_parser/lib/src/language/syntax_error.dart deleted file mode 100644 index 31de2dc6..00000000 --- a/packages/graphql/graphql_parser/lib/src/language/syntax_error.dart +++ /dev/null @@ -1,12 +0,0 @@ -import 'package:source_span/source_span.dart'; - -class SyntaxError implements Exception { - final String message; - final FileSpan span; - - SyntaxError(this.message, this.span); - - @override - String toString() => - 'Syntax error at ${span.start.toolString}: $message\n${span.highlight()}'; -} diff --git a/packages/graphql/graphql_parser/lib/src/language/token.dart b/packages/graphql/graphql_parser/lib/src/language/token.dart deleted file mode 100644 index 4a8498ae..00000000 --- a/packages/graphql/graphql_parser/lib/src/language/token.dart +++ /dev/null @@ -1,19 +0,0 @@ -import 'package:source_span/source_span.dart'; -import 'token_type.dart'; - -class Token { - final TokenType type; - final String text; - FileSpan span; - - Token(this.type, this.text, [this.span]); - - @override - String toString() { - if (span == null) { - return "'$text' -> $type"; - } else { - return "(${span.start.line}:${span.start.column}) '$text' -> $type"; - } - } -} diff --git a/packages/graphql/graphql_parser/lib/src/language/token_type.dart b/packages/graphql/graphql_parser/lib/src/language/token_type.dart deleted file mode 100644 index 8eb50aa2..00000000 --- a/packages/graphql/graphql_parser/lib/src/language/token_type.dart +++ /dev/null @@ -1,30 +0,0 @@ -enum TokenType { - ARROBA, - COLON, - COMMA, - DOLLAR, - ELLIPSIS, - EQUALS, - EXCLAMATION, - LBRACE, - RBRACE, - LBRACKET, - RBRACKET, - LPAREN, - RPAREN, - - // Note: these are *not* reserved names. - // FRAGMENT, - // MUTATION, - // SUBSCRIPTION, - // ON, - // QUERY, - // NULL - // BOOLEAN, - - NUMBER, - STRING, - BLOCK_STRING, - - NAME, -} diff --git a/packages/graphql/graphql_parser/mono_pkg.yaml b/packages/graphql/graphql_parser/mono_pkg.yaml deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/graphql/graphql_parser/pubspec.yaml b/packages/graphql/graphql_parser/pubspec.yaml deleted file mode 100644 index 108eacb1..00000000 --- a/packages/graphql/graphql_parser/pubspec.yaml +++ /dev/null @@ -1,15 +0,0 @@ -name: graphql_parser -version: 1.1.4 -description: Parses GraphQL queries and schemas. Also includes classes for the GraphQL AST. -author: Tobe O -homepage: https://github.com/angel-dart/graphql -environment: - sdk: '>=2.10.0 <2.12.0' -dependencies: - charcode: ^1.0.0 - source_span: ^1.0.0 - string_scanner: ^1.0.0 -dev_dependencies: - matcher: any - pedantic: ^1.0.0 - test: ^1.15.7 diff --git a/packages/graphql/graphql_parser/test/argument_test.dart b/packages/graphql/graphql_parser/test/argument_test.dart deleted file mode 100644 index fbe12542..00000000 --- a/packages/graphql/graphql_parser/test/argument_test.dart +++ /dev/null @@ -1,87 +0,0 @@ -import 'package:graphql_parser/graphql_parser.dart'; -import 'package:matcher/matcher.dart'; -import 'package:test/test.dart'; - -import 'common.dart'; - -main() { - test('argument', () { - expect('foo: 2', isArgument('foo', 2)); - expect(r'foo: $bar', isArgument('foo', 'bar')); - }); - - test('exception', () { - var isSyntaxError = predicate((x) { - var parser = parse(x.toString())..parseArgument(); - return parser.errors.isNotEmpty; - }, 'fails to parse argument'); - - var isSyntaxErrorOnArguments = predicate((x) { - var parser = parse(x.toString())..parseArguments(); - return parser.errors.isNotEmpty; - }, 'fails to parse arguments'); - - expect('foo', isSyntaxError); - expect('foo:', isSyntaxError); - expect(r'(foo: $bar', isSyntaxErrorOnArguments); - }); -} - -ArgumentContext parseArgument(String text) => parse(text).parseArgument(); - -List parseArgumentList(String text) => - parse(text).parseArguments(); - -Matcher isArgument(String name, value) => _IsArgument(name, value); - -Matcher isArgumentList(List arguments) => _IsArgumentList(arguments); - -class _IsArgument extends Matcher { - final String name; - final value; - - _IsArgument(this.name, this.value); - - @override - Description describe(Description description) { - return description.add('is an argument named "$name" with value $value'); - } - - @override - bool matches(item, Map matchState) { - var arg = item is ArgumentContext ? item : parseArgument(item.toString()); - if (arg == null) return false; - print(arg.span.highlight()); - - var v = arg.value; - return equals(name).matches(arg.name, matchState) && - ((v is VariableContext && equals(value).matches(v.name, matchState)) || - equals(value).matches(arg.value.computeValue({}), matchState)); - } -} - -class _IsArgumentList extends Matcher { - final List arguments; - - _IsArgumentList(this.arguments); - - @override - Description describe(Description description) { - return description.add('is list of ${arguments.length} argument(s)'); - } - - @override - bool matches(item, Map matchState) { - var args = item is List - ? item - : parse(item.toString()).parseArguments(); - - if (args.length != arguments.length) return false; - - for (int i = 0; i < args.length; i++) { - if (!arguments[i].matches(args[i], matchState)) return false; - } - - return true; - } -} diff --git a/packages/graphql/graphql_parser/test/comment_test.dart b/packages/graphql/graphql_parser/test/comment_test.dart deleted file mode 100644 index 5ca6a91e..00000000 --- a/packages/graphql/graphql_parser/test/comment_test.dart +++ /dev/null @@ -1,16 +0,0 @@ -import 'package:graphql_parser/graphql_parser.dart'; -import 'package:test/test.dart'; - -void main() { - test('heeds comments', () { - var tokens = scan(''' - # Hello - { - # Goodbye - } - # Bonjour - '''); - - expect(tokens, hasLength(2)); - }); -} diff --git a/packages/graphql/graphql_parser/test/common.dart b/packages/graphql/graphql_parser/test/common.dart deleted file mode 100644 index e30cb713..00000000 --- a/packages/graphql/graphql_parser/test/common.dart +++ /dev/null @@ -1,3 +0,0 @@ -import 'package:graphql_parser/graphql_parser.dart'; - -Parser parse(String text) => Parser(scan(text)); diff --git a/packages/graphql/graphql_parser/test/directive_test.dart b/packages/graphql/graphql_parser/test/directive_test.dart deleted file mode 100644 index 001c4ea8..00000000 --- a/packages/graphql/graphql_parser/test/directive_test.dart +++ /dev/null @@ -1,117 +0,0 @@ -import 'package:graphql_parser/graphql_parser.dart'; -import 'package:matcher/matcher.dart'; -import 'package:test/test.dart'; -import 'argument_test.dart'; -import 'common.dart'; - -main() { - test('name only', () { - expect('@foo', isDirective('foo')); - }); - - test('with value or variable', () { - expect('@foo: 2', isDirective('foo', valueOrVariable: equals(2))); - expect(r'@foo: $bar', isDirective('foo', valueOrVariable: equals('bar'))); - }); - - test('with argument', () { - expect('@foo (bar: 2)', isDirective('foo', argument: isArgument('bar', 2))); - expect(r'@foo (bar: $baz)', - isDirective('foo', argument: isArgument('bar', r'baz'))); - }); - - test('exceptions', () { - var isSyntaxError = predicate((x) { - var parser = parse(x.toString())..parseDirective(); - return parser.errors.isNotEmpty; - }, 'fails to parse directive'); - - expect('@', isSyntaxError); - expect('@foo:', isSyntaxError); - expect('@foo (', isSyntaxError); - expect('@foo (bar: 2', isSyntaxError); - expect('@foo (', isSyntaxError); - }); -} - -DirectiveContext parseDirective(String text) => parse(text).parseDirective(); - -Matcher isDirective(String name, {Matcher valueOrVariable, Matcher argument}) => - _IsDirective(name, valueOrVariable: valueOrVariable, argument: argument); - -Matcher isDirectiveList(List directives) => - _IsDirectiveList(directives); - -class _IsDirective extends Matcher { - final String name; - final Matcher valueOrVariable, argument; - - _IsDirective(this.name, {this.valueOrVariable, this.argument}); - - @override - Description describe(Description description) { - var desc = description.add('is a directive with name "$name"'); - - if (valueOrVariable != null) { - return valueOrVariable.describe(desc.add(' and ')); - } else if (argument != null) { - return argument.describe(desc.add(' and ')); - } else { - return desc; - } - } - - @override - bool matches(item, Map matchState) { - var directive = - item is DirectiveContext ? item : parseDirective(item.toString()); - if (directive == null) return false; - if (valueOrVariable != null) { - if (directive.value == null) { - return false; - } else { - var v = directive.value; - if (v is VariableContext) { - return valueOrVariable.matches(v.name, matchState); - } else { - return valueOrVariable.matches( - directive.value.computeValue({}), matchState); - } - } - } else if (argument != null) { - if (directive.argument == null) { - return false; - } else { - return argument.matches(directive.argument, matchState); - } - } else { - return true; - } - } -} - -class _IsDirectiveList extends Matcher { - final List directives; - - _IsDirectiveList(this.directives); - - @override - Description describe(Description description) { - return description.add('is list of ${directives.length} directive(s)'); - } - - @override - bool matches(item, Map matchState) { - var args = item is List - ? item - : parse(item.toString()).parseDirectives(); - - if (args.length != directives.length) return false; - - for (int i = 0; i < args.length; i++) { - if (!directives[i].matches(args[i], matchState)) return false; - } - - return true; - } -} diff --git a/packages/graphql/graphql_parser/test/document_test.dart b/packages/graphql/graphql_parser/test/document_test.dart deleted file mode 100644 index 914f6b43..00000000 --- a/packages/graphql/graphql_parser/test/document_test.dart +++ /dev/null @@ -1,119 +0,0 @@ -import 'package:graphql_parser/graphql_parser.dart'; -import 'package:test/test.dart'; - -import 'common.dart'; -import 'directive_test.dart'; -import 'field_test.dart'; -import 'selection_set_test.dart'; -import 'type_test.dart'; -import 'value_test.dart'; -import 'variable_definition_test.dart'; - -main() { - test('fragment', () { - var fragment = parse(''' - fragment PostInfo on Post { - description - comments { - id - } - } - ''').parseFragmentDefinition(); - - expect(fragment, isNotNull); - expect(fragment.name, 'PostInfo'); - expect(fragment.typeCondition.typeName.name, 'Post'); - expect( - fragment.selectionSet, - isSelectionSet([ - isField(fieldName: isFieldName('description')), - isField( - fieldName: isFieldName('comments'), - selectionSet: - isSelectionSet([isField(fieldName: isFieldName('id'))])), - ])); - }); - - test('fragment exceptions', () { - var throwsSyntaxError = predicate((x) { - var parser = parse(x.toString())..parseFragmentDefinition(); - return parser.errors.isNotEmpty; - }, 'fails to parse fragment definition'); - - expect('fragment', throwsSyntaxError); - expect('fragment foo', throwsSyntaxError); - expect('fragment foo on', throwsSyntaxError); - expect('fragment foo on bar', throwsSyntaxError); - }); - - group('operation', () { - test('with selection set', () { - var op = parse('{foo, bar: baz}').parseOperationDefinition(); - expect(op.variableDefinitions, isNull); - expect(op.isQuery, isTrue); - expect(op.isMutation, isFalse); - expect(op.name, isNull); - expect( - op.selectionSet, - isSelectionSet([ - isField(fieldName: isFieldName('foo')), - isField(fieldName: isFieldName('bar', alias: 'baz')) - ])); - }); - - test('mutation', () { - var op = parse('mutation {foo, bar: baz}').parseOperationDefinition(); - expect(op.variableDefinitions, isNull); - expect(op.isQuery, isFalse); - expect(op.isMutation, isTrue); - expect(op.name, isNull); - expect( - op.selectionSet, - isSelectionSet([ - isField(fieldName: isFieldName('foo')), - isField(fieldName: isFieldName('bar', alias: 'baz')) - ])); - }); - - test('with operation type', () { - var doc = - parse(r'query foo ($one: [int] = 2) @foo @bar: 2 {foo, bar: baz}') - .parseDocument(); - print(doc.span.highlight()); - expect(doc.definitions, hasLength(1)); - expect(doc.definitions.first is OperationDefinitionContext, isTrue); - var op = doc.definitions.first as OperationDefinitionContext; - expect(op.isMutation, isFalse); - expect(op.isQuery, isTrue); - - expect(op.variableDefinitions.variableDefinitions, hasLength(1)); - expect( - op.variableDefinitions.variableDefinitions.first, - isVariableDefinition('one', - type: isListType(isType('int'), isNullable: true), - defaultValue: isValue(2))); - - expect(op.directives, hasLength(2)); - expect(op.directives[0], isDirective('foo')); - expect(op.directives[1], isDirective('bar', valueOrVariable: equals(2))); - - expect(op.selectionSet, isNotNull); - expect( - op.selectionSet, - isSelectionSet([ - isField(fieldName: isFieldName('foo')), - isField(fieldName: isFieldName('bar', alias: 'baz')) - ])); - }); - - test('exceptions', () { - var throwsSyntaxError = predicate((x) { - var parser = parse(x.toString())..parseOperationDefinition(); - return parser.errors.isNotEmpty; - }, 'fails to parse operation definition'); - - expect('query', throwsSyntaxError); - expect('query foo()', throwsSyntaxError); - }); - }); -} diff --git a/packages/graphql/graphql_parser/test/field_test.dart b/packages/graphql/graphql_parser/test/field_test.dart deleted file mode 100644 index e39f3f63..00000000 --- a/packages/graphql/graphql_parser/test/field_test.dart +++ /dev/null @@ -1,143 +0,0 @@ -import 'package:graphql_parser/graphql_parser.dart'; -import 'package:test/test.dart'; - -import 'argument_test.dart'; -import 'common.dart'; -import 'directive_test.dart'; -import 'fragment_spread_test.dart'; -import 'selection_set_test.dart'; -import 'value_test.dart'; - -main() { - group('field name', () { - test('plain field name', () { - expect('foo', isFieldName('foo')); - }); - test('alias', () { - expect('foo: bar', isFieldName('foo', alias: 'bar')); - }); - test('exceptions', () { - var throwsSyntaxError = predicate((x) { - var parser = parse(x.toString())..parseFieldName(); - return parser.errors.isNotEmpty; - }, 'fails to parse field name'); - - expect('foo:', throwsSyntaxError); - }); - }); - - test('arguments', () { - expect('()', isArgumentList([])); - expect(r'(a: 2)', isArgumentList([isArgument('a', 2)])); - expect(r'(a: 2, b: $c)', - isArgumentList([isArgument('a', 2), isArgument('b', 'c')])); - }); - - group('field tests', () { - test('plain field name', () { - expect('foo', isField(fieldName: isFieldName('foo'))); - }); - - test('aliased field name', () { - expect('foo: bar', isField(fieldName: isFieldName('foo', alias: 'bar'))); - }); - - test('with arguments', () { - expect( - r'foo (a: 2, b: $c)', - isField( - fieldName: isFieldName('foo'), - arguments: - isArgumentList([isArgument('a', 2), isArgument('b', 'c')]))); - }); - - test('with directives', () { - expect( - 'foo: bar (a: 2) @bar @baz: 2 @quux (one: 1)', - isField( - fieldName: isFieldName('foo', alias: 'bar'), - arguments: isArgumentList([isArgument('a', 2)]), - directives: isDirectiveList([ - isDirective('bar'), - isDirective('baz', valueOrVariable: isValue(2)), - isDirective('quux', argument: isArgument('one', 1)) - ]))); - }); - - test('with selection set', () { - expect( - 'foo: bar {baz, ...quux}', - isField( - fieldName: isFieldName('foo', alias: 'bar'), - selectionSet: isSelectionSet([ - isField(fieldName: isFieldName('baz')), - isFragmentSpread('quux') - ]))); - }); - }); -} - -FieldContext parseField(String text) => parse(text).parseField(); - -FieldNameContext parseFieldName(String text) => parse(text).parseFieldName(); - -Matcher isField( - {Matcher fieldName, - Matcher arguments, - Matcher directives, - Matcher selectionSet}) => - _IsField(fieldName, arguments, directives, selectionSet); - -Matcher isFieldName(String name, {String alias}) => _IsFieldName(name, alias); - -class _IsField extends Matcher { - final Matcher fieldName, arguments, directives, selectionSet; - - _IsField(this.fieldName, this.arguments, this.directives, this.selectionSet); - - @override - Description describe(Description description) { - // Too lazy to make a real description... - return description.add('is field'); - } - - @override - bool matches(item, Map matchState) { - var field = item is FieldContext ? item : parseField(item.toString()); - if (field == null) return false; - if (fieldName != null && !fieldName.matches(field.fieldName, matchState)) { - return false; - } - if (arguments != null && !arguments.matches(field.arguments, matchState)) { - return false; - } - return true; - } -} - -class _IsFieldName extends Matcher { - final String name, realName; - - _IsFieldName(this.name, this.realName); - - @override - Description describe(Description description) { - if (realName != null) { - return description - .add('is field with name "$name" and alias "$realName"'); - } - return description.add('is field with name "$name"'); - } - - @override - bool matches(item, Map matchState) { - var fieldName = - item is FieldNameContext ? item : parseFieldName(item.toString()); - if (realName != null) { - return fieldName.alias?.alias == name && - fieldName.alias?.name == realName; - } else { - return fieldName.name == name; - } - } -} diff --git a/packages/graphql/graphql_parser/test/fragment_spread_test.dart b/packages/graphql/graphql_parser/test/fragment_spread_test.dart deleted file mode 100644 index 752e1122..00000000 --- a/packages/graphql/graphql_parser/test/fragment_spread_test.dart +++ /dev/null @@ -1,58 +0,0 @@ -import 'package:graphql_parser/graphql_parser.dart'; -import 'package:test/test.dart'; -import 'common.dart'; -import 'argument_test.dart'; -import 'directive_test.dart'; - -main() { - test('name only', () { - expect(['...foo', '... foo'], everyElement(isFragmentSpread('foo'))); - }); - - test('with directives', () { - expect( - '... foo @bar @baz: 2 @quux(one: 1)', - isFragmentSpread('foo', - directives: isDirectiveList([ - isDirective('bar'), - isDirective('baz', valueOrVariable: equals(2)), - isDirective('quux', argument: isArgument('one', 1)) - ]))); - }); -} - -FragmentSpreadContext parseFragmentSpread(String text) => - parse(text).parseFragmentSpread(); - -Matcher isFragmentSpread(String name, {Matcher directives}) => - _IsFragmentSpread(name, directives); - -class _IsFragmentSpread extends Matcher { - final String name; - final Matcher directives; - - _IsFragmentSpread(this.name, this.directives); - - @override - Description describe(Description description) { - if (directives != null) { - return directives.describe( - description.add('is a fragment spread named "$name" that also ')); - } - return description.add('is a fragment spread named "$name"'); - } - - @override - bool matches(item, Map matchState) { - var spread = item is FragmentSpreadContext - ? item - : parseFragmentSpread(item.toString()); - if (spread == null) return false; - if (spread.name != name) return false; - if (directives != null) { - return directives.matches(spread.directives, matchState); - } else { - return true; - } - } -} diff --git a/packages/graphql/graphql_parser/test/inline_fragment_test.dart b/packages/graphql/graphql_parser/test/inline_fragment_test.dart deleted file mode 100644 index 1936e820..00000000 --- a/packages/graphql/graphql_parser/test/inline_fragment_test.dart +++ /dev/null @@ -1,76 +0,0 @@ -import 'package:graphql_parser/graphql_parser.dart'; -import 'package:test/test.dart'; -import 'common.dart'; -import 'argument_test.dart'; -import 'directive_test.dart'; -import 'field_test.dart'; -import 'fragment_spread_test.dart'; -import 'selection_set_test.dart'; - -main() { - test('no directives', () { - expect( - '... on foo {bar, baz: quux}', - isInlineFragment('foo', - selectionSet: isSelectionSet([ - isField(fieldName: isFieldName('bar')), - isField(fieldName: isFieldName('baz', alias: 'quux')) - ]))); - }); - - test('with directives', () { - expect( - '... on foo @bar @baz: 2 @quux(one: 1) {... bar}', - isInlineFragment('foo', - directives: isDirectiveList([ - isDirective('bar'), - isDirective('baz', valueOrVariable: equals(2)), - isDirective('quux', argument: isArgument('one', 1)) - ]), - selectionSet: isSelectionSet([isFragmentSpread('bar')]))); - }); - - test('exceptions', () { - var throwsSyntaxError = predicate((x) { - var parser = parse(x.toString())..parseInlineFragment(); - return parser.errors.isNotEmpty; - }, 'fails to parse inline fragment'); - expect('... on foo', throwsSyntaxError); - expect('... on foo @bar', throwsSyntaxError); - expect('... on', throwsSyntaxError); - expect('...', throwsSyntaxError); - }); -} - -InlineFragmentContext parseInlineFragment(String text) => - parse(text).parseInlineFragment(); - -Matcher isInlineFragment(String name, - {Matcher directives, Matcher selectionSet}) => - _IsInlineFragment(name, directives, selectionSet); - -class _IsInlineFragment extends Matcher { - final String name; - final Matcher directives, selectionSet; - - _IsInlineFragment(this.name, this.directives, this.selectionSet); - - @override - Description describe(Description description) { - return description.add('is an inline fragment named "$name"'); - } - - @override - bool matches(item, Map matchState) { - var fragment = item is InlineFragmentContext - ? item - : parseInlineFragment(item.toString()); - if (fragment == null) return false; - if (fragment.typeCondition.typeName.name != name) return false; - if (directives != null && - !directives.matches(fragment.directives, matchState)) return false; - if (selectionSet != null && - !selectionSet.matches(fragment.selectionSet, matchState)) return false; - return true; - } -} diff --git a/packages/graphql/graphql_parser/test/issue23_test.dart b/packages/graphql/graphql_parser/test/issue23_test.dart deleted file mode 100644 index 6ab4950a..00000000 --- a/packages/graphql/graphql_parser/test/issue23_test.dart +++ /dev/null @@ -1,94 +0,0 @@ -import 'package:graphql_parser/graphql_parser.dart'; -import 'package:test/test.dart'; - -/// This is an *extremely* verbose test, but basically it -/// parses both documents, and makes sure that $memberId has -/// a valid value. -/// -/// Resolves https://github.com/angel-dart/graphql/issues/23. -void main() { - void testStr(String name, String text) { - test('name', () { - final List tokens = scan(text); - final Parser parser = Parser(tokens); - - if (parser.errors.isNotEmpty) { - print(parser.errors.toString()); - } - expect(parser.errors, isEmpty); - - // Parse the GraphQL document using recursive descent - final DocumentContext doc = parser.parseDocument(); - - expect(doc.definitions, isNotNull); - expect(doc.definitions, isNotEmpty); - - // Sanity check - var queryDef = doc.definitions[0] as OperationDefinitionContext; - expect(queryDef.isQuery, true); - expect(queryDef.name, 'customerMemberAttributes'); - expect(queryDef.variableDefinitions.variableDefinitions, hasLength(1)); - var memberIdDef = queryDef.variableDefinitions.variableDefinitions[0]; - expect(memberIdDef.variable.name, 'memberId'); - - // Find $memberId - var customerByCustomerId = queryDef.selectionSet.selections[0]; - var customerMemberAttributesByCustomerId = - customerByCustomerId.field.selectionSet.selections[0]; - var nodes0 = - customerMemberAttributesByCustomerId.field.selectionSet.selections[0]; - var customerMemberAttributeId = nodes0.field.selectionSet.selections[0]; - expect(customerMemberAttributeId.field.fieldName.name, - 'customerMemberAttributeId'); - var memberAttr = nodes0.field.selectionSet.selections[1]; - expect(memberAttr.field.fieldName.name, - 'memberAttributesByCustomerMemberAttributeId'); - expect(memberAttr.field.arguments, hasLength(1)); - var condition = memberAttr.field.arguments[0]; - expect(condition.name, 'condition'); - expect(condition.value, TypeMatcher()); - var conditionValue = condition.value as ObjectValueContext; - var memberId = conditionValue.fields - .singleWhere((f) => f.nameToken.text == 'memberId'); - expect(memberId.value, TypeMatcher()); - print('Found \$memberId: Instance of $T'); - }); - } - - testStr('member id as var', memberIdAsVar); - testStr('member id as constant', memberIdAsConstant); -} - -final String memberIdAsVar = r''' -query customerMemberAttributes($memberId: Int!){ - customerByCustomerId(customerId: 7) { - customerMemberAttributesByCustomerId { - nodes { - customerMemberAttributeId - memberAttributesByCustomerMemberAttributeId(condition: {memberId: $memberId}) { - nodes { - memberAttributeId - } - } - } - } - } -} -'''; - -final String memberIdAsConstant = r''' -query customerMemberAttributes($memberId: Int!){ - customerByCustomerId(customerId: 7) { - customerMemberAttributesByCustomerId { - nodes { - customerMemberAttributeId - memberAttributesByCustomerMemberAttributeId(condition: {memberId: 7}) { - nodes { - memberAttributeId - } - } - } - } - } -} -'''; diff --git a/packages/graphql/graphql_parser/test/next_name_test.dart b/packages/graphql/graphql_parser/test/next_name_test.dart deleted file mode 100644 index 353ffdbf..00000000 --- a/packages/graphql/graphql_parser/test/next_name_test.dart +++ /dev/null @@ -1,24 +0,0 @@ -import 'package:test/test.dart'; -import 'common.dart'; - -var githubSrc = r''' -query searchRepos($queryString: String!, $repositoryOrder: RepositoryOrder, $first: Int!) { - search(type: REPOSITORY, query: $queryString, first: $first) { - ...SearchResultItemConnection - } -} -'''; - -void main() { - test('can parse formerly-reserved words', () { - var def = parse(githubSrc).parseOperationDefinition(); - expect(def.isQuery, isTrue); - expect(def.variableDefinitions.variableDefinitions, hasLength(3)); - - var searchField = def.selectionSet.selections[0].field; - expect(searchField.fieldName.name, 'search'); - - var argNames = searchField.arguments.map((a) => a.name).toList(); - expect(argNames, ['type', 'query', 'first']); - }); -} diff --git a/packages/graphql/graphql_parser/test/selection_set_test.dart b/packages/graphql/graphql_parser/test/selection_set_test.dart deleted file mode 100644 index cd482481..00000000 --- a/packages/graphql/graphql_parser/test/selection_set_test.dart +++ /dev/null @@ -1,96 +0,0 @@ -import 'package:graphql_parser/graphql_parser.dart'; -import 'package:test/test.dart'; -import 'common.dart'; -import 'field_test.dart'; -import 'fragment_spread_test.dart'; -import 'inline_fragment_test.dart'; - -main() { - test('empty', () { - expect('{}', isSelectionSet([])); - }); - - test('with commas', () { - expect( - '{foo, bar: baz}', - isSelectionSet([ - isField(fieldName: isFieldName('foo')), - isField(fieldName: isFieldName('bar', alias: 'baz')) - ])); - }); - - test('no commas', () { - expect( - ''' - { - foo - bar: baz ...quux - ... on foo {bar, baz} - }''' - .split('\n') - .map((s) => s.trim()) - .join(' '), - isSelectionSet([ - isField(fieldName: isFieldName('foo')), - isField(fieldName: isFieldName('bar', alias: 'baz')), - isFragmentSpread('quux'), - isInlineFragment('foo', - selectionSet: isSelectionSet([ - isField(fieldName: isFieldName('bar')), - isField(fieldName: isFieldName('baz')), - ])) - ])); - }); - - test('exceptions', () { - var throwsSyntaxError = predicate((x) { - var parser = parse(x.toString())..parseSelectionSet(); - return parser.errors.isNotEmpty; - }, 'fails to parse selection set'); - - expect('{foo,bar,baz', throwsSyntaxError); - }); -} - -SelectionSetContext parseSelectionSet(String text) => - parse(text).parseSelectionSet(); - -Matcher isSelectionSet(List selections) => _IsSelectionSet(selections); - -class _IsSelectionSet extends Matcher { - final List selections; - - _IsSelectionSet(this.selections); - - @override - Description describe(Description description) { - return description - .add('is selection set with ${selections.length} selection(s)'); - } - - @override - bool matches(item, Map matchState) { - var set = - item is SelectionSetContext ? item : parseSelectionSet(item.toString()); - - // if (set != null) { - // print('Item: $set has ${set.selections.length} selection(s):'); - // for (var s in set.selections) { - // print(' * $s (${s.span.text})'); - // } - // } - - if (set == null) return false; - if (set.selections.length != selections.length) return false; - - for (int i = 0; i < set.selections.length; i++) { - var sel = set.selections[i]; - if (!selections[i].matches( - sel.field ?? sel.fragmentSpread ?? sel.inlineFragment, matchState)) { - return false; - } - } - - return true; - } -} diff --git a/packages/graphql/graphql_parser/test/type_test.dart b/packages/graphql/graphql_parser/test/type_test.dart deleted file mode 100644 index 93b017ca..00000000 --- a/packages/graphql/graphql_parser/test/type_test.dart +++ /dev/null @@ -1,101 +0,0 @@ -import 'package:graphql_parser/graphql_parser.dart'; -import 'package:test/test.dart'; -import 'common.dart'; - -main() { - test('nullable', () { - expect('foo', isType('foo', isNullable: true)); - }); - - test('non-nullable', () { - expect('foo!', isType('foo', isNullable: false)); - }); - - group('list type', () { - group('nullable list type', () { - test('with nullable', () { - expect('[foo]', isListType(isType('foo', isNullable: true))); - }); - - test('with non-nullable', () { - expect('[foo!]', isListType(isType('foo', isNullable: false))); - }); - }); - - group('non-nullable list type', () { - test('with nullable', () { - expect('[foo]!', - isListType(isType('foo', isNullable: true), isNullable: false)); - }); - - test('with non-nullable', () { - expect('[foo!]!', - isListType(isType('foo', isNullable: false), isNullable: false)); - }); - }); - - test('exceptions', () { - var throwsSyntaxError = predicate((x) { - var parser = parse(x.toString())..parseType(); - return parser.errors.isNotEmpty; - }, 'fails to parse type'); - - expect('[foo', throwsSyntaxError); - expect('[', throwsSyntaxError); - }); - }); -} - -TypeContext parseType(String text) => parse(text).parseType(); - -Matcher isListType(Matcher innerType, {bool isNullable}) => - _IsListType(innerType, isNullable: isNullable != false); - -Matcher isType(String name, {bool isNullable}) => - _IsType(name, nonNull: isNullable != true); - -class _IsListType extends Matcher { - final Matcher innerType; - final bool isNullable; - - _IsListType(this.innerType, {this.isNullable}); - - @override - Description describe(Description description) { - var tok = isNullable != false ? 'nullable' : 'non-nullable'; - var desc = description.add('is $tok list type with an inner type that '); - return innerType.describe(desc); - } - - @override - bool matches(item, Map matchState) { - var type = item is TypeContext ? item : parseType(item.toString()); - if (type.listType == null) return false; - if (type.isNullable != (isNullable != false)) return false; - return innerType.matches(type.listType.innerType, matchState); - } -} - -class _IsType extends Matcher { - final String name; - final bool nonNull; - - _IsType(this.name, {this.nonNull}); - - @override - Description describe(Description description) { - if (nonNull == true) { - return description.add('is non-null type named "$name"'); - } else { - return description.add('is nullable type named "$name"'); - } - } - - @override - bool matches(item, Map matchState) { - var type = item is TypeContext ? item : parseType(item.toString()); - if (type.typeName == null) return false; - var result = type.typeName.name == name; - return result && type.isNullable == !(nonNull == true); - } -} diff --git a/packages/graphql/graphql_parser/test/value_test.dart b/packages/graphql/graphql_parser/test/value_test.dart deleted file mode 100644 index a5edaaaf..00000000 --- a/packages/graphql/graphql_parser/test/value_test.dart +++ /dev/null @@ -1,93 +0,0 @@ -import 'dart:math' as math; - -import 'package:graphql_parser/graphql_parser.dart'; -import 'package:test/test.dart'; - -import 'common.dart'; - -main() { - test('boolean', () { - expect('true', isValue(true)); - expect('false', isValue(false)); - }); - - test('number', () { - expect('1', isValue(1)); - expect('1.0', isValue(1.0)); - expect('-1', isValue(-1)); - expect('-1.0', isValue(-1.0)); - expect('6.26e-34', isValue(6.26 * math.pow(10, -34))); - expect('-6.26e-34', isValue(-6.26 * math.pow(10, -34))); - expect('-6.26e34', isValue(-6.26 * math.pow(10, 34))); - }); - - test('array', () { - expect('[]', isValue([])); - expect('[1,2]', isValue([1, 2])); - expect('[1,2, 3]', isValue([1, 2, 3])); - expect('["a"]', isValue(['a'])); - }); - - test('string', () { - expect('""', isValue('')); - expect('"a"', isValue('a')); - expect('"abc"', isValue('abc')); - expect('"\\""', isValue('"')); - expect('"\\b"', isValue('\b')); - expect('"\\f"', isValue('\f')); - expect('"\\n"', isValue('\n')); - expect('"\\r"', isValue('\r')); - expect('"\\t"', isValue('\t')); - expect('"\\u0123"', isValue('\u0123')); - expect('"\\u0123\\u4567"', isValue('\u0123\u4567')); - }); - - test('block string', () { - expect('""""""', isValue('')); - expect('"""abc"""', isValue('abc')); - expect('"""\n\n\nabc\n\n\n"""', isValue('abc')); - }); - - test('object', () { - expect('{}', isValue({})); - expect('{a: 2}', isValue({'a': 2})); - expect('{a: 2, b: "c"}', isValue({'a': 2, 'b': 'c'})); - }); - - test('null', () { - expect('null', isValue(null)); - }); - - test('enum', () { - expect('FOO_BAR', isValue('FOO_BAR')); - }); - - test('exceptions', () { - var throwsSyntaxError = predicate((x) { - var parser = parse(x.toString())..parseInputValue(); - return parser.errors.isNotEmpty; - }, 'fails to parse value'); - - expect('[1', throwsSyntaxError); - }); -} - -InputValueContext parseValue(String text) => parse(text).parseInputValue(); - -Matcher isValue(value) => _IsValue(value); - -class _IsValue extends Matcher { - final value; - - _IsValue(this.value); - - @override - Description describe(Description description) => - description.add('equals $value when parsed as a GraphQL value'); - - @override - bool matches(item, Map matchState) { - var v = item is InputValueContext ? item : parseValue(item.toString()); - return equals(value).matches(v.computeValue({}), matchState); - } -} diff --git a/packages/graphql/graphql_parser/test/variable_definition_test.dart b/packages/graphql/graphql_parser/test/variable_definition_test.dart deleted file mode 100644 index f3380aea..00000000 --- a/packages/graphql/graphql_parser/test/variable_definition_test.dart +++ /dev/null @@ -1,88 +0,0 @@ -import 'package:graphql_parser/graphql_parser.dart'; -import 'package:test/test.dart'; - -import 'common.dart'; -import 'type_test.dart'; -import 'value_test.dart'; - -main() { - test('no default value', () { - expect(r'$foo: bar', - isVariableDefinition('foo', type: isType('bar', isNullable: true))); - }); - - test('default value', () { - expect( - r'$foo: int! = 2', - isVariableDefinition('foo', - type: isType('int', isNullable: false), defaultValue: isValue(2))); - }); - - test('exceptions', () { - var throwsSyntaxError = predicate((x) { - var parser = parse(x.toString())..parseVariableDefinition(); - return parser.errors.isNotEmpty; - }, 'fails to parse variable definition'); - - var throwsSyntaxErrorOnDefinitions = predicate((x) { - var parser = parse(x.toString())..parseVariableDefinitions(); - return parser.errors.isNotEmpty; - }, 'fails to parse variable definitions'); - - expect(r'$foo', throwsSyntaxError); - expect(r'$foo:', throwsSyntaxError); - expect(r'$foo: int =', throwsSyntaxError); - - expect(r'($foo: int = 2', throwsSyntaxErrorOnDefinitions); - }); -} - -VariableDefinitionContext parseVariableDefinition(String text) => - parse(text).parseVariableDefinition(); - -Matcher isVariableDefinition(String name, - {Matcher type, Matcher defaultValue}) => - _IsVariableDefinition(name, type, defaultValue); - -class _IsVariableDefinition extends Matcher { - final String name; - final Matcher type, defaultValue; - - _IsVariableDefinition(this.name, this.type, this.defaultValue); - - @override - Description describe(Description description) { - var desc = description.add('is variable definition with name "$name"'); - - if (type != null) { - desc = type.describe(desc.add(' with type that ')); - } - - if (defaultValue != null) { - desc = type.describe(desc.add(' with default value that ')); - } - - return desc; - } - - @override - bool matches(item, Map matchState) { - var def = item is VariableDefinitionContext - ? item - : parseVariableDefinition(item.toString()); - if (def == null) return false; - if (def.variable.name != name) return false; - bool result = true; - - if (type != null) { - result == result && type.matches(def.type, matchState); - } - - if (defaultValue != null) { - result = - result && defaultValue.matches(def.defaultValue.value, matchState); - } - - return result; - } -} diff --git a/packages/graphql/graphql_parser/test/variable_test.dart b/packages/graphql/graphql_parser/test/variable_test.dart deleted file mode 100644 index eb9759f3..00000000 --- a/packages/graphql/graphql_parser/test/variable_test.dart +++ /dev/null @@ -1,43 +0,0 @@ -import 'package:test/test.dart'; - -import 'common.dart'; - -main() { - test('variables', () { - expect(r'$a', isVariable('a')); - expect(r'$abc', isVariable('abc')); - expect(r'$abc123', isVariable('abc123')); - expect(r'$_', isVariable('_')); - expect(r'$___', isVariable('___')); - expect(r'$_123', isVariable('_123')); - }); - - test('exceptions', () { - var throwsSyntaxError = predicate((x) { - var parser = parse(x.toString())..parseVariable(); - return parser.errors.isNotEmpty; - }, 'fails to parse variable'); - - expect(r'$', throwsSyntaxError); - }); -} - -Matcher isVariable(String name) => _IsVariable(name); - -class _IsVariable extends Matcher { - final String name; - - _IsVariable(this.name); - - @override - Description describe(Description description) { - return description.add('parses as a variable named "$name"'); - } - - @override - bool matches(item, Map matchState) { - var p = parse(item.toString()); - var v = p.parseVariable(); - return equals(name).matches(v?.name, matchState); - } -} diff --git a/packages/graphql/graphql_schema/.gitignore b/packages/graphql/graphql_schema/.gitignore deleted file mode 100644 index 26517d3b..00000000 --- a/packages/graphql/graphql_schema/.gitignore +++ /dev/null @@ -1,93 +0,0 @@ -# See https://www.dartlang.org/tools/private-files.html - -# Files and directories created by pub -.buildlog -.packages -.project -.pub/ -.scripts-bin/ -build/ -**/packages/ - -# Files created by dart2js -# (Most Dart developers will use pub build to compile Dart, use/modify these -# rules if you intend to use dart2js directly -# Convention is to use extension '.dart.js' for Dart compiled to Javascript to -# differentiate from explicit Javascript files) -*.dart.js -*.part.js -*.js.deps -*.js.map -*.info.json - -# Directory created by dartdoc -doc/api/ - -# Don't commit pubspec lock file -# (Library packages only! Remove pattern if developing an application package) -pubspec.lock -### Dart template -# See https://www.dartlang.org/tools/private-files.html - -# Files and directories created by pub - -# SDK 1.20 and later (no longer creates packages directories) - -# Older SDK versions -# (Include if the minimum SDK version specified in pubsepc.yaml is earlier than 1.20) - - -# Files created by dart2js -# (Most Dart developers will use pub build to compile Dart, use/modify these -# rules if you intend to use dart2js directly -# Convention is to use extension '.dart.js' for Dart compiled to Javascript to -# differentiate from explicit Javascript files) - -# Directory created by dartdoc - -# Don't commit pubspec lock file -# (Library packages only! Remove pattern if developing an application package) -### JetBrains template -# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm -# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 - -# User-specific stuff: -../.idea/workspace.xml -.idea/**/tasks.xml -.idea/dictionaries - -# Sensitive or high-churn files: -.idea/**/dataSources/ -.idea/**/dataSources.ids -.idea/**/dataSources.xml -.idea/**/dataSources.local.xml -.idea/**/sqlDataSources.xml -.idea/**/dynamic.xml -.idea/**/uiDesigner.xml - -# Gradle: -.idea/**/gradle.xml -.idea/**/libraries - -# Mongo Explorer plugin: -.idea/**/mongoSettings.xml - -## File-based project format: -*.iws - -## Plugin-specific files: - -# IntelliJ -/out/ - -# mpeltonen/sbt-idea plugin -.idea_modules/ - -# JIRA plugin -atlassian-ide-plugin.xml - -# Crashlytics plugin (for Android Studio and IntelliJ) -com_crashlytics_export_strings.xml -crashlytics.properties -crashlytics-build.properties -fabric.properties diff --git a/packages/graphql/graphql_schema/CHANGELOG.md b/packages/graphql/graphql_schema/CHANGELOG.md deleted file mode 100644 index ee521008..00000000 --- a/packages/graphql/graphql_schema/CHANGELOG.md +++ /dev/null @@ -1,12 +0,0 @@ -# 1.0.4 -* Add `convert` method to types, to avoid some annoying generics bugs. - -# 1.0.3 -* `enumTypeFromStrings` now returns `GraphQLEnumType`. - -# 1.0.2 -* Added `GraphQLClass()`. -* Added `typeName`. - -# 1.0.1 -* Dart 2 updates. \ No newline at end of file diff --git a/packages/graphql/graphql_schema/LICENSE b/packages/graphql/graphql_schema/LICENSE deleted file mode 100644 index 89074fd3..00000000 --- a/packages/graphql/graphql_schema/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2017 The Angel Framework - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/packages/graphql/graphql_schema/README.md b/packages/graphql/graphql_schema/README.md deleted file mode 100644 index dd3d76c1..00000000 --- a/packages/graphql/graphql_schema/README.md +++ /dev/null @@ -1,156 +0,0 @@ -# graphql_schema -[![Pub](https://img.shields.io/pub/v/graphql_schema.svg)](https://pub.dartlang.org/packages/graphql_schema) -[![build status](https://travis-ci.org/angel-dart/graphql.svg)](https://travis-ci.org/angel-dart/graphql) - -An implementation of GraphQL's type system in Dart. Supports any platform where Dart runs. -The decisions made in the design of this library were done to make the experience -as similar to the JavaScript reference implementation as possible, and to also -correctly implement the official specification. - -Contains functionality to build *all* GraphQL types: -* `String` -* `Int` -* `Float` -* `Boolean` -* `GraphQLObjectType` -* `GraphQLUnionType` -* `GraphQLEnumType` -* `GraphQLInputObjectType` -* `Date` - ISO-8601 Date string, deserializes to a Dart `DateTime` object - -Of course, for a full description of GraphQL's type system, see the official -specification: -http://facebook.github.io/graphql/October2016/ - -Mostly analogous to `graphql-js`; many names are verbatim: -https://graphql.org/graphql-js/type/ - -# Usage -It's easy to define a schema with the -[helper functions](#helpers): - -```dart -final GraphQLSchema todoSchema = new GraphQLSchema( - query: objectType('Todo', [ - field('text', graphQLString.nonNullable()), - field('created_at', graphQLDate) -])); -``` - -All GraphQL types are generic, in order to leverage Dart's strong typing support. - -# Serialization -GraphQL types can `serialize` and `deserialize` input data. -The exact implementation of this depends on the type. - -```dart -var iso8601String = graphQLDate.serialize(new DateTime.now()); -var date = graphQLDate.deserialize(iso8601String); -print(date.millisecondsSinceEpoch); -``` - -# Validation -GraphQL types can `validate` input data. - -```dart -var validation = myType.validate('@root', {...}); - -if (validation.successful) { - doSomething(validation.value); -} else { - print(validation.errors); -} -``` - -# Helpers -* `graphQLSchema` - Create a `GraphQLSchema` -* `objectType` - Create a `GraphQLObjectType` with fields -* `field` - Create a `GraphQLField` with a type/argument/resolver -* `listOf` - Create a `GraphQLListType` with the provided `innerType` -* `inputObjectType` - Creates a `GraphQLInputObjectType` -* `inputField` - Creates a field for a `GraphQLInputObjectType` - -# Types -All of the GraphQL scalar types are built in, as well as a `Date` type: -* `graphQLString` -* `graphQLId` -* `graphQLBoolean` -* `graphQLInt` -* `graphQLFloat` -* `graphQLDate` - -## Non-Nullable Types -You can easily make a type non-nullable by calling its `nonNullable` method. - -## List Types -Support for list types is also included. Use the `listType` helper for convenience. - -```dart -/// A non-nullable list of non-nullable integers -listOf(graphQLInt.nonNullable()).nonNullable(); -``` - -### Input values and parameters -Take the following GraphQL query: - -```graphql -{ - anime { - characters(title: "Hunter x Hunter") { - name - age - } - } -} -``` - -And subsequently, its schema: - -```graphql -type AnimeQuery { - characters($title: String!): [Character!] -} - -type Character { - name: String - age: Int -} -``` - -The field `characters` accepts a parameter, `title`. To reproduce this in -`package:graphql_schema`, use `GraphQLFieldInput`: - -```dart -final GraphQLObjectType queryType = objectType('AnimeQuery', fields: [ - field('characters', - listOf(characterType.nonNullable()), - inputs: [ - new GraphQLFieldInput('title', graphQLString.nonNullable()) - ] - ), -]); - -final GraphQLObjectType characterType = objectType('Character', fields: [ - field('name', graphQLString), - field('age', graphQLInt), -]); -``` - -In the majority of cases where you use GraphQL, you will be delegate the -actual fetching of data to a database object, or some asynchronous resolver -function. - -`package:graphql_schema` includes this functionality in the `resolve` property, -which is passed a context object and a `Map` of arguments. - -A hypothetical example of the above might be: - -```dart -var field = field( - 'characters', - graphQLString, - resolve: (_, args) async { - return await myDatabase.findCharacters(args['title']); - }, -); -``` \ No newline at end of file diff --git a/packages/graphql/graphql_schema/analysis_options.yaml b/packages/graphql/graphql_schema/analysis_options.yaml deleted file mode 100644 index eae1e42a..00000000 --- a/packages/graphql/graphql_schema/analysis_options.yaml +++ /dev/null @@ -1,3 +0,0 @@ -analyzer: - strong-mode: - implicit-casts: false \ No newline at end of file diff --git a/packages/graphql/graphql_schema/example/example.dart b/packages/graphql/graphql_schema/example/example.dart deleted file mode 100644 index fa6cb25f..00000000 --- a/packages/graphql/graphql_schema/example/example.dart +++ /dev/null @@ -1,41 +0,0 @@ -import 'package:graphql_schema/graphql_schema.dart'; - -final GraphQLSchema todoSchema = new GraphQLSchema( - queryType: objectType('Todo', fields: [ - field( - 'text', - graphQLString.nonNullable(), - resolve: resolveToNull, - ), - field( - 'created_at', - graphQLDate, - resolve: resolveToNull, - ), - ]), -); - -main() { - // Validation - var validation = todoSchema.queryType.validate( - '@root', - { - 'foo': 'bar', - 'text': null, - 'created_at': 24, - }, - ); - - if (validation.successful) { - print('This is valid data!!!'); - } else { - print('Invalid data.'); - validation.errors.forEach((s) => print(' * $s')); - } - - // Serialization - print(todoSchema.queryType.serialize({ - 'text': 'Clean your room!', - 'created_at': new DateTime.now().subtract(new Duration(days: 10)) - })); -} diff --git a/packages/graphql/graphql_schema/graphql_schema.iml b/packages/graphql/graphql_schema/graphql_schema.iml deleted file mode 100644 index 0854fb6e..00000000 --- a/packages/graphql/graphql_schema/graphql_schema.iml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/packages/graphql/graphql_schema/lib/graphql_schema.dart b/packages/graphql/graphql_schema/lib/graphql_schema.dart deleted file mode 100644 index b4f7c362..00000000 --- a/packages/graphql/graphql_schema/lib/graphql_schema.dart +++ /dev/null @@ -1 +0,0 @@ -export 'src/schema.dart'; diff --git a/packages/graphql/graphql_schema/lib/src/argument.dart b/packages/graphql/graphql_schema/lib/src/argument.dart deleted file mode 100644 index cf9ea795..00000000 --- a/packages/graphql/graphql_schema/lib/src/argument.dart +++ /dev/null @@ -1,52 +0,0 @@ -part of graphql_schema.src.schema; - -/// An input to a GraphQL field. This is analogous to a function parameter in Dart. -class GraphQLFieldInput { - /// The name of this field. - final String name; - - /// The type that input values must conform to. - final GraphQLType type; - - /// An optional default value for this field. - final Value defaultValue; - - /// An optional description for this field. - /// - /// This is useful when documenting your API for consumers like GraphiQL. - final String description; - - /// If [defaultValue] is `null`, and `null` is a valid value for this parameter, set this to `true`. - final bool defaultsToNull; - - static bool _isInputTypeOrScalar(GraphQLType type) { - if (type is GraphQLInputObjectType) { - return true; - } else if (type is GraphQLUnionType) { - return type.possibleTypes.every(_isInputTypeOrScalar); - } else if (type is GraphQLObjectType) { - return false; - } else if (type is GraphQLNonNullableType) { - return _isInputTypeOrScalar(type.ofType); - } else if (type is GraphQLListType) { - return _isInputTypeOrScalar(type.ofType); - } else { - return true; - } - } - - GraphQLFieldInput(this.name, this.type, - {this.defaultValue, this.defaultsToNull: false, this.description}) { - assert(_isInputTypeOrScalar(type), - 'All inputs to a GraphQL field must either be scalar types, or explicitly marked as INPUT_OBJECT. Call `GraphQLObjectType.asInputObject()` on any object types you are passing as inputs to a field.'); - } - - @override - bool operator ==(other) => - other is GraphQLFieldInput && - other.name == name && - other.type == type && - other.defaultValue == other.defaultValue && - other.defaultsToNull == defaultsToNull && - other.description == description; -} diff --git a/packages/graphql/graphql_schema/lib/src/enum.dart b/packages/graphql/graphql_schema/lib/src/enum.dart deleted file mode 100644 index 74acc910..00000000 --- a/packages/graphql/graphql_schema/lib/src/enum.dart +++ /dev/null @@ -1,104 +0,0 @@ -part of graphql_schema.src.schema; - -/// Shorthand for building a [GraphQLEnumType]. -GraphQLEnumType enumType(String name, Map values, - {String description}) { - return new GraphQLEnumType( - name, values.keys.map((k) => new GraphQLEnumValue(k, values[k])).toList(), - description: description); -} - -/// Shorthand for building a [GraphQLEnumType] where all the possible values -/// are mapped to Dart strings. -GraphQLEnumType enumTypeFromStrings(String name, List values, - {String description}) { - return new GraphQLEnumType( - name, values.map((s) => new GraphQLEnumValue(s, s)).toList(), - description: description); -} - -/// A [GraphQLType] with only a predetermined number of possible values. -/// -/// Though these are serialized as strings, they carry special meaning with a type system. -class GraphQLEnumType extends GraphQLScalarType - with _NonNullableMixin { - /// The name of this enum type. - final String name; - - /// The defined set of possible values for this type. - /// - /// No other values will be accepted than the ones you define. - final List> values; - - /// A description of this enum type, for tools like GraphiQL. - final String description; - - GraphQLEnumType(this.name, this.values, {this.description}); - - @override - String serialize(Value value) { - if (value == null) return null; - return values.firstWhere((v) => v.value == value).name; - } - - @override - Value deserialize(String serialized) { - return values.firstWhere((v) => v.name == serialized).value; - } - - @override - ValidationResult validate(String key, String input) { - if (!values.any((v) => v.name == input)) { - if (input == null) { - return new ValidationResult._failure( - ['The enum "$name" does not accept null values.']); - } - - return new ValidationResult._failure( - ['"$input" is not a valid value for the enum "$name".']); - } - - return new ValidationResult._ok(input); - } - - @override - bool operator ==(other) => - other is GraphQLEnumType && - other.name == name && - other.description == description && - const ListEquality().equals(other.values, values); - - @override - GraphQLType coerceToInputObject() => this; -} - -/// A known value of a [GraphQLEnumType]. -/// -/// In practice, you might not directly call this constructor very often. -class GraphQLEnumValue { - /// The name of this value. - final String name; - - /// The Dart value associated with enum values bearing the given [name]. - final Value value; - - /// An optional description of this value; useful for tools like GraphiQL. - final String description; - - /// The reason, if any, that this value was deprecated, if it indeed is deprecated. - final String deprecationReason; - - GraphQLEnumValue(this.name, this.value, - {this.description, this.deprecationReason}); - - /// Returns `true` if this value has a [deprecationReason]. - bool get isDeprecated => deprecationReason != null; - - @override - bool operator ==(other) => - other is GraphQLEnumValue && - other.name == name && - other.value == value && - other.description == description && - other.deprecationReason == deprecationReason; -} diff --git a/packages/graphql/graphql_schema/lib/src/field.dart b/packages/graphql/graphql_schema/lib/src/field.dart deleted file mode 100644 index 6f8b1a2c..00000000 --- a/packages/graphql/graphql_schema/lib/src/field.dart +++ /dev/null @@ -1,62 +0,0 @@ -part of graphql_schema.src.schema; - -/// Typedef for a function that resolves the value of a [GraphQLObjectField], whether asynchronously or not. -typedef FutureOr GraphQLFieldResolver( - Serialized serialized, Map argumentValues); - -/// A field on a [GraphQLObjectType]. -/// -/// It can have input values and additional documentation, and explicitly declares it shape -/// within the schema. -class GraphQLObjectField { - /// The list of input values this field accepts, if any. - final List inputs = []; - - /// The name of this field in serialized input. - final String name; - - /// A function used to evaluate the value of this field, with respect to an arbitrary Dart value. - final GraphQLFieldResolver resolve; - - /// The [GraphQLType] associated with values that this field's [resolve] callback returns. - final GraphQLType type; - - /// An optional description of this field; useful for tools like GraphiQL. - final String description; - - /// The reason that this field, if it is deprecated, was deprecated. - final String deprecationReason; - - GraphQLObjectField(this.name, this.type, - {Iterable arguments: const [], - @required this.resolve, - this.deprecationReason, - this.description}) { - assert(type != null, 'GraphQL fields must specify a `type`.'); -// assert( -// resolve != null, 'GraphQL fields must specify a `resolve` callback.'); - this.inputs.addAll(arguments ?? []); - } - - /// Returns `true` if this field has a [deprecationReason]. - bool get isDeprecated => deprecationReason?.isNotEmpty == true; - - FutureOr serialize(Value value) { - return type.serialize(value); - } - - FutureOr deserialize(Serialized serialized, - [Map argumentValues = const {}]) { - if (resolve != null) return resolve(serialized, argumentValues); - return type.deserialize(serialized); - } - - @override - bool operator ==(other) => - other is GraphQLObjectField && - other.name == name && - other.deprecationReason == deprecationReason && - other.type == type && - other.resolve == resolve && - const ListEquality().equals(other.inputs, inputs); -} diff --git a/packages/graphql/graphql_schema/lib/src/gen.dart b/packages/graphql/graphql_schema/lib/src/gen.dart deleted file mode 100644 index 40b5efe3..00000000 --- a/packages/graphql/graphql_schema/lib/src/gen.dart +++ /dev/null @@ -1,49 +0,0 @@ -part of graphql_schema.src.schema; - -/// Shorthand for generating a [GraphQLObjectType]. -GraphQLObjectType objectType(String name, - {String description, - bool isInterface: false, - Iterable fields = const [], - Iterable interfaces = const []}) { - var obj = new GraphQLObjectType(name, description, isInterface: isInterface) - ..fields.addAll(fields ?? []); - - if (interfaces?.isNotEmpty == true) { - for (var i in interfaces) { - obj.inheritFrom(i); - } - } - - return obj; -} - -/// Shorthand for generating a [GraphQLObjectField]. -GraphQLObjectField field( - String name, GraphQLType type, - {Iterable> inputs: const [], - GraphQLFieldResolver resolve, - String deprecationReason, - String description}) { - return new GraphQLObjectField(name, type, - arguments: inputs, - resolve: resolve, - description: description, - deprecationReason: deprecationReason); -} - -/// Shorthand for generating a [GraphQLInputObjectType]. -GraphQLInputObjectType inputObjectType(String name, - {String description, - Iterable inputFields: const []}) { - return new GraphQLInputObjectType(name, - description: description, inputFields: inputFields); -} - -/// Shorthand for generating a [GraphQLInputObjectField]. -GraphQLInputObjectField inputField( - String name, GraphQLType type, - {String description, T defaultValue}) { - return new GraphQLInputObjectField(name, type, - description: description, defaultValue: defaultValue); -} diff --git a/packages/graphql/graphql_schema/lib/src/object_type.dart b/packages/graphql/graphql_schema/lib/src/object_type.dart deleted file mode 100644 index 2447aed5..00000000 --- a/packages/graphql/graphql_schema/lib/src/object_type.dart +++ /dev/null @@ -1,299 +0,0 @@ -part of graphql_schema.src.schema; - -/// A [GraphQLType] that specifies the shape of structured data, with multiple fields that can be resolved independently of one another. -class GraphQLObjectType - extends GraphQLType, Map> - with _NonNullableMixin, Map> { - /// The name of this type. - final String name; - - /// An optional description of this type; useful for tools like GraphiQL. - final String description; - - /// The list of fields that an object of this type is expected to have. - final List fields = []; - - /// `true` if this type should be treated as an *interface*, which child types can [inheritFrom]. - /// - /// In GraphQL, the parent class is *aware* of all the [possibleTypes] that can implement it. - final bool isInterface; - - final List _interfaces = []; - - final List _possibleTypes = []; - - /// A list of other types that this object type is known to implement. - List get interfaces => - new List.unmodifiable(_interfaces); - - /// A list of other types that implement this interface. - List get possibleTypes => - new List.unmodifiable(_possibleTypes); - - GraphQLObjectType(this.name, this.description, {this.isInterface: false}); - - @override - GraphQLType, Map> - coerceToInputObject() { - return toInputObject('${name}Input', description: description); - } - - /// Converts [this] into a [GraphQLInputObjectType]. - GraphQLInputObjectType toInputObject(String name, {String description}) { - return new GraphQLInputObjectType(name, - description: description ?? this.description, - inputFields: fields.map((f) => new GraphQLInputObjectField( - f.name, f.type.coerceToInputObject(), - description: f.description))); - } - - /// Declares that this type inherits from another parent type. - /// - /// This also has the side effect of notifying the parent that this type is its descendant. - void inheritFrom(GraphQLObjectType other) { - if (!_interfaces.contains(other)) { - _interfaces.add(other); - other._possibleTypes.add(this); - other._interfaces.forEach(inheritFrom); - } - } - - @override - ValidationResult> validate(String key, Map input) { - if (input is! Map) - return new ValidationResult._failure(['Expected "$key" to be a Map.']); - - if (isInterface) { - List errors = []; - - for (var type in possibleTypes) { - var result = type.validate(key, input); - - if (result.successful) { - return result; - } else { - errors.addAll(result.errors); - } - } - - return new ValidationResult>._failure(errors); - } - - var out = {}; - List errors = []; - - for (var field in fields) { - if (field.type is GraphQLNonNullableType) { - if (!input.containsKey(field.name) || input[field.name] == null) { - errors.add( - 'Field "${field.name}, of type ${field.type} cannot be null."'); - } - } - } - - input.keys.forEach((k) { - var field = fields.firstWhere((f) => f.name == k, orElse: () => null); - - if (field == null) { - errors.add( - 'Unexpected field "$k" encountered in $key. Accepted values on type $name: ${fields.map((f) => f.name).toList()}'); - } else { - var v = input[k]; - var result = field.type.validate(k.toString(), field.type.convert(v)); - - if (!result.successful) { - errors.addAll(result.errors.map((s) => '$key: $s')); - } else { - out[k] = v; - } - } - }); - - if (errors.isNotEmpty) { - return new ValidationResult._failure(errors); - } else - return new ValidationResult._ok(_foldToStringDynamic(out)); - } - - @override - Map serialize(Map value) { - return value.keys.fold>({}, (out, k) { - var field = fields.firstWhere((f) => f.name == k, orElse: () => null); - if (field == null) - throw new UnsupportedError( - 'Cannot serialize field "$k", which was not defined in the schema.'); - return out..[k.toString()] = field.serialize(value[k]); - }); - } - - @override - Map deserialize(Map value) { - return value.keys.fold>({}, (out, k) { - var field = fields.firstWhere((f) => f.name == k, orElse: () => null); - if (field == null) - throw new UnsupportedError('Unexpected field "$k" encountered in map.'); - return out..[k.toString()] = field.deserialize(value[k]); - }); - } - - /// Returns `true` if this type, or any of its parents, is a direct descendant of another given [type]. - bool isImplementationOf(GraphQLObjectType type) { - if (type == this) { - return true; - } else if (interfaces.contains(type)) { - return true; - } else if (interfaces.isNotEmpty) { - return interfaces.any((t) => t.isImplementationOf(type)); - } else { - return false; - } - } - - @override - bool operator ==(other) { - return other is GraphQLObjectType && - other.name == name && - other.description == description && - other.isInterface == isInterface && - const ListEquality().equals(other.fields, fields) && -// const ListEquality() Removed, as it causes a stack overflow :( -// .equals(other.interfaces, interfaces) && - const ListEquality() - .equals(other.possibleTypes, possibleTypes); - } -} - -Map _foldToStringDynamic(Map map) { - return map == null - ? null - : map.keys.fold>( - {}, (out, k) => out..[k.toString()] = map[k]); -} - -/// A special [GraphQLType] that specifies the shape of an object that can only be used as an input to a [GraphQLField]. -/// -/// GraphQL input object types are different from regular [GraphQLObjectType]s in that they do not support resolution, -/// and are overall more limiter in utility, because their only purpose is to reduce the number of parameters to a given field, -/// and to potentially reuse an input structure across multiple fields in the hierarchy. -class GraphQLInputObjectType - extends GraphQLType, Map> - with _NonNullableMixin, Map> { - /// The name of this type. - final String name; - - /// An optional type of this type, which is useful for tools like GraphiQL. - final String description; - - /// A list of the fields that an input object of this type is expected to have. - final List inputFields = []; - - GraphQLInputObjectType(this.name, - {this.description, - Iterable inputFields: const []}) { - this.inputFields.addAll(inputFields ?? const []); - } - - @override - ValidationResult> validate(String key, Map input) { - if (input is! Map) - return new ValidationResult._failure(['Expected "$key" to be a Map.']); - - var out = {}; - List errors = []; - - for (var field in inputFields) { - if (field.type is GraphQLNonNullableType) { - if (!input.containsKey(field.name) || input[field.name] == null) { - errors.add( - 'Field "${field.name}, of type ${field.type} cannot be null."'); - } - } - } - - input.keys.forEach((k) { - var field = - inputFields.firstWhere((f) => f.name == k, orElse: () => null); - - if (field == null) { - errors.add( - 'Unexpected field "$k" encountered in $key. Accepted values on type $name: ${inputFields.map((f) => f.name).toList()}'); - } else { - var v = input[k]; - var result = field.type.validate(k.toString(), v); - - if (!result.successful) { - errors.addAll(result.errors.map((s) => '$key: $s')); - } else { - out[k] = v; - } - } - }); - - if (errors.isNotEmpty) { - return new ValidationResult._failure(errors); - } else - return new ValidationResult._ok(_foldToStringDynamic(out)); - } - - @override - Map serialize(Map value) { - return value.keys.fold>({}, (out, k) { - var field = - inputFields.firstWhere((f) => f.name == k, orElse: () => null); - if (field == null) - throw new UnsupportedError( - 'Cannot serialize field "$k", which was not defined in the schema.'); - return out..[k.toString()] = field.type.serialize(value[k]); - }); - } - - @override - Map deserialize(Map value) { - return value.keys.fold>({}, (out, k) { - var field = - inputFields.firstWhere((f) => f.name == k, orElse: () => null); - if (field == null) - throw new UnsupportedError('Unexpected field "$k" encountered in map.'); - return out..[k.toString()] = field.type.deserialize(value[k]); - }); - } - - @override - bool operator ==(other) { - return other is GraphQLInputObjectType && - other.name == name && - other.description == description && - const ListEquality() - .equals(other.inputFields, inputFields); - } - - @override - GraphQLType, Map> - coerceToInputObject() => this; -} - -/// A field expected within a [GraphQLInputObjectType]. -class GraphQLInputObjectField { - /// The name of this field. - final String name; - - /// The type that a value for this field is validated against. - final GraphQLType type; - - /// A description of this field, which is useful for tools like GraphiQL. - final String description; - - /// An optional default value for this field in an input object. - final Value defaultValue; - - GraphQLInputObjectField(this.name, this.type, - {this.description, this.defaultValue}); - - @override - bool operator ==(other) => - other is GraphQLInputObjectField && - other.name == name && - other.type == type && - other.description == description && - other.defaultValue == defaultValue; -} diff --git a/packages/graphql/graphql_schema/lib/src/scalar.dart b/packages/graphql/graphql_schema/lib/src/scalar.dart deleted file mode 100644 index 1b997358..00000000 --- a/packages/graphql/graphql_schema/lib/src/scalar.dart +++ /dev/null @@ -1,158 +0,0 @@ -part of graphql_schema.src.schema; - -/// `true` or `false`. -final GraphQLScalarType graphQLBoolean = new _GraphQLBoolType(); - -/// A UTF‐8 character sequence. -final GraphQLScalarType graphQLString = - new _GraphQLStringType._(); - -/// The ID scalar type represents a unique identifier, often used to re-fetch an object or as the key for a cache. -/// -/// The ID type is serialized in the same way as a String; however, defining it as an ID signifies that it is not intended to be human‐readable. -final GraphQLScalarType graphQLId = - new _GraphQLStringType._('ID'); - -/// A [DateTime], serialized as an ISO-8601 string.. -final GraphQLScalarType graphQLDate = - new _GraphQLDateType._(); - -/// A signed 32‐bit integer. -final GraphQLScalarType graphQLInt = new _GraphQLNumType( - 'Int', 'A signed 64-bit integer.', (x) => x is int, 'an integer'); - -/// A signed double-precision floating-point value. -final GraphQLScalarType graphQLFloat = - new _GraphQLNumType( - 'Float', - 'A signed double-precision floating-point value.', - (x) => x is double, - 'a float'); - -abstract class GraphQLScalarType - extends GraphQLType - with _NonNullableMixin { - Type get valueType => Value; -} - -typedef bool _NumVerifier(x); - -class _GraphQLBoolType extends GraphQLScalarType { - @override - bool serialize(bool value) { - return value; - } - - @override - String get name => 'Boolean'; - - @override - String get description => 'A boolean value; can be either true or false.'; - - @override - ValidationResult validate(String key, input) { - if (input != null && input is! bool) - return new ValidationResult._failure( - ['Expected "$key" to be a boolean.']); - return new ValidationResult._ok(input); - } - - @override - bool deserialize(bool serialized) { - return serialized; - } - - @override - GraphQLType coerceToInputObject() => this; -} - -class _GraphQLNumType extends GraphQLScalarType { - final String name; - final String description; - final _NumVerifier verifier; - final String expected; - - _GraphQLNumType(this.name, this.description, this.verifier, this.expected); - - @override - ValidationResult validate(String key, input) { - if (input != null && !verifier(input)) - return new ValidationResult._failure( - ['Expected "$key" to be $expected.']); - - return new ValidationResult._ok(input); - } - - @override - T deserialize(T serialized) { - return serialized; - } - - @override - T serialize(T value) { - return value; - } - - @override - GraphQLType coerceToInputObject() => this; -} - -class _GraphQLStringType extends GraphQLScalarType { - final String name; - - _GraphQLStringType._([this.name = 'String']); - - @override - String get description => 'A character sequence.'; - - @override - String serialize(String value) => value; - - @override - String deserialize(String serialized) => serialized; - - @override - ValidationResult validate(String key, input) => - input == null || input is String - ? new ValidationResult._ok(input) - : new ValidationResult._failure(['Expected "$key" to be a string.']); - - @override - GraphQLType coerceToInputObject() => this; -} - -class _GraphQLDateType extends GraphQLScalarType - with _NonNullableMixin { - _GraphQLDateType._(); - - @override - String get name => 'Date'; - - @override - String get description => 'An ISO-8601 Date.'; - - @override - String serialize(DateTime value) => value.toIso8601String(); - - @override - DateTime deserialize(String serialized) => DateTime.parse(serialized); - - @override - ValidationResult validate(String key, input) { - if (input != null && input is! String) - return new ValidationResult._failure( - ['$key must be an ISO 8601-formatted date string.']); - else if (input == null) return new ValidationResult._ok(input); - - try { - DateTime.parse(input); - return new ValidationResult._ok(input); - } on FormatException { - return new ValidationResult._failure( - ['$key must be an ISO 8601-formatted date string.']); - } - } - - @override - GraphQLType coerceToInputObject() => this; -} diff --git a/packages/graphql/graphql_schema/lib/src/schema.dart b/packages/graphql/graphql_schema/lib/src/schema.dart deleted file mode 100644 index e32add0c..00000000 --- a/packages/graphql/graphql_schema/lib/src/schema.dart +++ /dev/null @@ -1,159 +0,0 @@ -library graphql_schema.src.schema; - -import 'dart:async'; - -import 'package:collection/collection.dart'; -import 'package:meta/meta.dart'; -import 'package:source_span/source_span.dart'; - -part 'argument.dart'; - -part 'enum.dart'; - -part 'field.dart'; - -part 'gen.dart'; - -part 'object_type.dart'; - -part 'scalar.dart'; - -part 'type.dart'; - -part 'union.dart'; - -part 'validation_result.dart'; - -/// The schema against which queries, mutations, and subscriptions are executed. -class GraphQLSchema { - /// The shape which all queries against the backend must take. - final GraphQLObjectType queryType; - - /// The shape required for any query that changes the state of the backend. - final GraphQLObjectType mutationType; - - /// A [GraphQLObjectType] describing the form of data sent to real-time subscribers. - /// - /// Note that as of August 4th, 2018 (when this text was written), subscriptions are not formalized - /// in the GraphQL specification. Therefore, any GraphQL implementation can potentially implement - /// subscriptions in its own way. - final GraphQLObjectType subscriptionType; - - GraphQLSchema({this.queryType, this.mutationType, this.subscriptionType}); -} - -/// A shorthand for creating a [GraphQLSchema]. -GraphQLSchema graphQLSchema( - {@required GraphQLObjectType queryType, - GraphQLObjectType mutationType, - GraphQLObjectType subscriptionType}) => - new GraphQLSchema( - queryType: queryType, - mutationType: mutationType, - subscriptionType: subscriptionType); - -/// A default resolver that always returns `null`. -resolveToNull(_, __) => null; - -/// An exception that occurs during execution of a GraphQL query. -class GraphQLException implements Exception { - /// A list of all specific errors, with text representation, that caused this exception. - final List errors; - - GraphQLException(this.errors); - - factory GraphQLException.fromMessage(String message) { - return new GraphQLException([ - new GraphQLExceptionError(message), - ]); - } - - factory GraphQLException.fromSourceSpan(String message, FileSpan span) { - return new GraphQLException([ - new GraphQLExceptionError( - message, - locations: [ - new GraphExceptionErrorLocation.fromSourceLocation(span.start), - ], - ), - ]); - } - - Map>> toJson() { - return { - 'errors': errors.map((e) => e.toJson()).toList(), - }; - } -} - -/// One of an arbitrary number of errors that may occur during the execution of a GraphQL query. -/// -/// This will almost always be passed to a [GraphQLException], as it is useless alone. -class GraphQLExceptionError { - /// The reason execution was halted, whether it is a syntax error, or a runtime error, or some other exception. - final String message; - - /// An optional list of locations within the source text where this error occurred. - /// - /// Smart tools can use this information to show end users exactly which part of the errant query - /// triggered an error. - final List locations; - - GraphQLExceptionError(this.message, {this.locations: const []}); - - Map toJson() { - var out = {'message': message}; - if (locations?.isNotEmpty == true) { - out['locations'] = locations.map((l) => l.toJson()).toList(); - } - return out; - } -} - -/// Information about a location in source text that caused an error during the execution of a GraphQL query. -/// -/// This is analogous to a [SourceLocation] from `package:source_span`. -class GraphExceptionErrorLocation { - final int line; - final int column; - - GraphExceptionErrorLocation(this.line, this.column); - - factory GraphExceptionErrorLocation.fromSourceLocation( - SourceLocation location) { - return new GraphExceptionErrorLocation(location.line, location.column); - } - - Map toJson() { - return {'line': line, 'column': column}; - } -} - -typedef GraphQLType GraphDocumentationTypeProvider(); - -/// A metadata annotation used to provide documentation to `package:graphql_server`. -class GraphQLDocumentation { - /// The description of the annotated class, field, or enum value, to be displayed in tools like GraphiQL. - final String description; - - /// The reason the annotated field or enum value was deprecated, if any. - final String deprecationReason; - - /// A constant callback that returns an explicit type for the annotated field, rather than having it be assumed - /// via `dart:mirrors`. - final GraphDocumentationTypeProvider type; - - /// The name of an explicit type for the annotated field, rather than having it be assumed. - final Symbol typeName; - - const GraphQLDocumentation( - {this.description, this.deprecationReason, this.type, this.typeName}); -} - -/// The canonical instance. -const GraphQLClass graphQLClass = const GraphQLClass._(); - -/// Signifies that a class should statically generate a [GraphQLSchema]. -class GraphQLClass { - const GraphQLClass._(); -} diff --git a/packages/graphql/graphql_schema/lib/src/type.dart b/packages/graphql/graphql_schema/lib/src/type.dart deleted file mode 100644 index a5c3034e..00000000 --- a/packages/graphql/graphql_schema/lib/src/type.dart +++ /dev/null @@ -1,170 +0,0 @@ -part of graphql_schema.src.schema; - -/// Strictly dictates the structure of some input data in a GraphQL query. -/// -/// GraphQL's rigid type system is primarily implemented in Dart using classes that extend from [GraphQLType]. -/// -/// A [GraphQLType] represents values of type [Value] as values of type [Serialized]; for example, a -/// [GraphQLType] that serializes objects into `String`s. -abstract class GraphQLType { - /// The name of this type. - String get name; - - /// A description of this type, which, while optional, can be very useful in tools like GraphiQL. - String get description; - - /// Serializes an arbitrary input value. - Serialized serialize(Value value); - - /// Deserializes a serialized value. - Value deserialize(Serialized serialized); - - /// Attempts to cast a dynamic [value] into a [Serialized] instance. - Serialized convert(value) => value as Serialized; - - /// Performs type coercion against an [input] value, and returns a list of errors if the validation was unsuccessful. - ValidationResult validate(String key, Serialized input); - - /// Creates a non-nullable type that represents this type, and enforces that a field of this type is present in input data. - GraphQLType nonNullable(); - - /// Turns this type into one suitable for being provided as an input to a [GraphQLObjectField]. - GraphQLType coerceToInputObject(); - - @override - String toString() => name; -} - -/// Shorthand to create a [GraphQLListType]. -GraphQLListType listOf( - GraphQLType innerType) => - new GraphQLListType(innerType); - -/// A special [GraphQLType] that indicates that input vales should be a list of another type, [ofType]. -class GraphQLListType - extends GraphQLType, List> - with _NonNullableMixin, List> { - final GraphQLType ofType; - - GraphQLListType(this.ofType); - - @override - List convert(value) { - if (value is Iterable) { - return value.cast().toList(); - } else { - return super.convert(value); - } - } - - @override - String get name => null; - - @override - String get description => - 'A list of items of type ${ofType.name ?? '(${ofType.description}).'}'; - - @override - ValidationResult> validate( - String key, List input) { - if (input is! List) - return new ValidationResult._failure(['Expected "$key" to be a list.']); - - List out = []; - List errors = []; - - for (int i = 0; i < input.length; i++) { - var k = '"$key" at index $i'; - var v = input[i]; - var result = ofType.validate(k, v); - if (!result.successful) - errors.addAll(result.errors); - else - out.add(v); - } - - if (errors.isNotEmpty) return new ValidationResult._failure(errors); - return new ValidationResult._ok(out); - } - - @override - List deserialize(List serialized) { - return serialized.map(ofType.deserialize).toList(); - } - - @override - List serialize(List value) { - return value.map(ofType.serialize).toList(); - } - - @override - String toString() => '[$ofType]'; - - @override - bool operator ==(other) => other is GraphQLListType && other.ofType == ofType; - - @override - GraphQLType, List> coerceToInputObject() => - new GraphQLListType(ofType.coerceToInputObject()); -} - -abstract class _NonNullableMixin - implements GraphQLType { - GraphQLType _nonNullableCache; - - GraphQLType nonNullable() => _nonNullableCache ??= - new GraphQLNonNullableType._(this); -} - -/// A special [GraphQLType] that indicates that input values should both be non-null, and be valid when asserted against another type, named [ofType]. -class GraphQLNonNullableType - extends GraphQLType { - final GraphQLType ofType; - - GraphQLNonNullableType._(this.ofType); - - @override - String get name => null; //innerType.name; - - @override - String get description => - 'A non-nullable binding to ${ofType.name ?? '(${ofType.description}).'}'; - - @override - GraphQLType nonNullable() { - throw new UnsupportedError( - 'Cannot call nonNullable() on a non-nullable type.'); - } - - @override - ValidationResult validate(String key, Serialized input) { - if (input == null) - return new ValidationResult._failure( - ['Expected "$key" to be a non-null value.']); - return ofType.validate(key, input); - } - - @override - Value deserialize(Serialized serialized) { - return ofType.deserialize(serialized); - } - - @override - Serialized serialize(Value value) { - return ofType.serialize(value); - } - - @override - String toString() { - return '$ofType!'; - } - - @override - bool operator ==(other) => - other is GraphQLNonNullableType && other.ofType == ofType; - - @override - GraphQLType coerceToInputObject() { - return ofType.coerceToInputObject().nonNullable(); - } -} diff --git a/packages/graphql/graphql_schema/lib/src/union.dart b/packages/graphql/graphql_schema/lib/src/union.dart deleted file mode 100644 index e6d8bc9a..00000000 --- a/packages/graphql/graphql_schema/lib/src/union.dart +++ /dev/null @@ -1,88 +0,0 @@ -part of graphql_schema.src.schema; - -/// A special [GraphQLType] that indicates that an input value may be valid against one or more [possibleTypes]. -/// -/// All provided types must be [GraphQLObjectType]s. -class GraphQLUnionType - extends GraphQLType, Map> - with _NonNullableMixin, Map> { - /// The name of this type. - final String name; - - /// A list of all types that conform to this union. - final List possibleTypes = []; - - GraphQLUnionType( - this.name, - Iterable, Map>> - possibleTypes) { - assert(possibleTypes.every((t) => t is GraphQLObjectType), - 'The member types of a Union type must all be Object base types; Scalar, Interface and Union types must not be member types of a Union. Similarly, wrapping types must not be member types of a Union.'); - assert(possibleTypes.isNotEmpty, - 'A Union type must define one or more member types.'); - - for (var t in possibleTypes.toSet()) { - this.possibleTypes.add(t as GraphQLObjectType); - } - } - - @override - String get description => possibleTypes.map((t) => t.name).join(' | '); - - @override - GraphQLType, Map> - coerceToInputObject() { - return new GraphQLUnionType( - '${name}Input', possibleTypes.map((t) => t.coerceToInputObject())); - } - - @override - Map serialize(Map value) { - for (var type in possibleTypes) { - try { - if (type.validate('@root', value).successful) { - return type.serialize(value); - } - } catch (_) {} - } - - throw new ArgumentError(); - } - - @override - Map deserialize(Map serialized) { - for (var type in possibleTypes) { - try { - return type.deserialize(serialized); - } catch (_) {} - } - - throw new ArgumentError(); - } - - @override - ValidationResult> validate( - String key, Map input) { - List errors = []; - - for (var type in possibleTypes) { - var result = type.validate(key, input); - - if (result.successful) { - return result; - } else { - errors.addAll(result.errors); - } - } - - return new ValidationResult>._failure(errors); - } - - @override - bool operator ==(other) => - other is GraphQLUnionType && - other.name == name && - other.description == description && - const ListEquality() - .equals(other.possibleTypes, possibleTypes); -} diff --git a/packages/graphql/graphql_schema/lib/src/validation_result.dart b/packages/graphql/graphql_schema/lib/src/validation_result.dart deleted file mode 100644 index 4a85d10f..00000000 --- a/packages/graphql/graphql_schema/lib/src/validation_result.dart +++ /dev/null @@ -1,28 +0,0 @@ -part of graphql_schema.src.schema; - -/// Represents the result of asserting an input [value] against a [GraphQLType]. - -class ValidationResult { - /// `true` if there were no errors during validation. - final bool successful; - - /// The input value passed to whatever caller invoked validation. - final Value value; - - /// A list of errors that caused validation to fail. - final List errors; - - ValidationResult._(this.successful, this.value, this.errors); - - ValidationResult._ok(this.value) - : errors = [], - successful = true; - - ValidationResult._failure(this.errors) - : value = null, - successful = false; - -// ValidationResult _asFailure() { -// return new ValidationResult._(false, value, errors); -// } -} diff --git a/packages/graphql/graphql_schema/mono_pkg.yaml b/packages/graphql/graphql_schema/mono_pkg.yaml deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/graphql/graphql_schema/pubspec.yaml b/packages/graphql/graphql_schema/pubspec.yaml deleted file mode 100644 index f61613c2..00000000 --- a/packages/graphql/graphql_schema/pubspec.yaml +++ /dev/null @@ -1,13 +0,0 @@ -name: graphql_schema -version: 1.0.4 -description: An implementation of GraphQL's type system in Dart. Basis of graphql_server. -author: Tobe O -homepage: https://github.com/angel-dart/graphql -environment: - sdk: '>=2.10.0 <2.12.0' -dependencies: - collection: ^1.0.0 - meta: ^1.0.0 - source_span: ^1.0.0 -dev_dependencies: - test: ^1.15.7 \ No newline at end of file diff --git a/packages/graphql/graphql_schema/test/common.dart b/packages/graphql/graphql_schema/test/common.dart deleted file mode 100644 index 01b7636d..00000000 --- a/packages/graphql/graphql_schema/test/common.dart +++ /dev/null @@ -1,15 +0,0 @@ -import 'package:graphql_schema/graphql_schema.dart'; - -final GraphQLObjectType pokemonType = objectType('Pokemon', fields: [ - field('species', graphQLString), - field('catch_date', graphQLDate) -]); - -final GraphQLObjectType trainerType = - objectType('Trainer', fields: [field('name', graphQLString)]); - -final GraphQLObjectType pokemonRegionType = objectType('PokemonRegion', - fields: [ - field('trainer', trainerType), - field('pokemon_species', listOf(pokemonType)) - ]); diff --git a/packages/graphql/graphql_schema/test/equality_test.dart b/packages/graphql/graphql_schema/test/equality_test.dart deleted file mode 100644 index a5fb2e70..00000000 --- a/packages/graphql/graphql_schema/test/equality_test.dart +++ /dev/null @@ -1,113 +0,0 @@ -import 'package:graphql_schema/graphql_schema.dart'; -import 'package:test/test.dart'; - -/// Note: this doesn't test for scalar types, which are final, and therefore use built-in equality. -void main() { - group('equality', () { - test('enums', () { - expect(enumTypeFromStrings('A', ['B', 'C']), - enumTypeFromStrings('A', ['B', 'C'])); - expect(enumTypeFromStrings('A', ['B', 'C']), - isNot(enumTypeFromStrings('B', ['B', 'C']))); - }); - - test('objects', () { - expect( - objectType('B', fields: [ - field('b', graphQLString.nonNullable()), - ]), - objectType('B', fields: [ - field('b', graphQLString.nonNullable()), - ]), - ); - - expect( - objectType('B', fields: [ - field('b', graphQLString.nonNullable()), - ]), - isNot(objectType('BD', fields: [ - field('b', graphQLString.nonNullable()), - ])), - ); - - expect( - objectType('B', fields: [ - field('b', graphQLString.nonNullable()), - ]), - isNot(objectType('B', fields: [ - field('ba', graphQLString.nonNullable()), - ])), - ); - - expect( - objectType('B', fields: [ - field('b', graphQLString.nonNullable()), - ]), - isNot(objectType('B', fields: [ - field('a', graphQLFloat.nonNullable()), - ])), - ); - }); - - test('input type', () {}); - - test('union type', () { - expect( - new GraphQLUnionType('A', [ - objectType('B', fields: [ - field('b', graphQLString.nonNullable()), - ]), - objectType('C', fields: [ - field('c', graphQLString.nonNullable()), - ]), - ]), - new GraphQLUnionType('A', [ - objectType('B', fields: [ - field('b', graphQLString.nonNullable()), - ]), - objectType('C', fields: [ - field('c', graphQLString.nonNullable()), - ]), - ]), - ); - - expect( - new GraphQLUnionType('A', [ - objectType('B', fields: [ - field('b', graphQLString.nonNullable()), - ]), - objectType('C', fields: [ - field('c', graphQLString.nonNullable()), - ]), - ]), - isNot(new GraphQLUnionType('AA', [ - objectType('B', fields: [ - field('b', graphQLString.nonNullable()), - ]), - objectType('C', fields: [ - field('c', graphQLString.nonNullable()), - ]), - ])), - ); - - expect( - new GraphQLUnionType('A', [ - objectType('BB', fields: [ - field('b', graphQLString.nonNullable()), - ]), - objectType('C', fields: [ - field('c', graphQLString.nonNullable()), - ]), - ]), - isNot(new GraphQLUnionType('AA', [ - objectType('BDD', fields: [ - field('b', graphQLString.nonNullable()), - ]), - objectType('C', fields: [ - field('c', graphQLString.nonNullable()), - ]), - ])), - ); - }); - }); -} diff --git a/packages/graphql/graphql_schema/test/inheritance_test.dart b/packages/graphql/graphql_schema/test/inheritance_test.dart deleted file mode 100644 index 8671c6dd..00000000 --- a/packages/graphql/graphql_schema/test/inheritance_test.dart +++ /dev/null @@ -1,67 +0,0 @@ -import 'package:graphql_schema/graphql_schema.dart'; -import 'package:test/test.dart'; - -void main() { - group('interface', () { - var a = objectType( - 'A', - isInterface: true, - fields: [ - field('text', graphQLString.nonNullable()), - ], - ); - - var b = objectType( - 'B', - isInterface: true, - interfaces: [a], - fields: [ - field('text', graphQLString.nonNullable()), - ], - ); - - var c = objectType( - 'C', - isInterface: true, - interfaces: [b], - fields: [ - field('text', graphQLString.nonNullable()), - ], - ); - - test('child implements parent', () { - expect(b.isImplementationOf(a), true); - expect(c.isImplementationOf(b), true); - }); - - test('parent does not implement child', () { - expect(a.isImplementationOf(b), false); - }); - - test('child interfaces contains parent', () { - expect(b.interfaces, contains(a)); - expect(c.interfaces, contains(b)); - }); - - test('parent possibleTypes contains child', () { - expect(a.possibleTypes, contains(b)); - expect(b.possibleTypes, contains(c)); - }); - - test('grandchild implements grandparent', () { - expect(c.isImplementationOf(a), true); - }); - - test('grandparent does not implement grandchild', () { - expect(a.isImplementationOf(c), false); - }); - - test('grandchild interfaces contains grandparent', () { - expect(c.interfaces, contains(a)); - }); - - test('grandparent possibleTypes contains grandchild', () { - expect(a.possibleTypes, contains(c)); - }); - }); -} diff --git a/packages/graphql/graphql_schema/test/serialize_test.dart b/packages/graphql/graphql_schema/test/serialize_test.dart deleted file mode 100644 index 997afca6..00000000 --- a/packages/graphql/graphql_schema/test/serialize_test.dart +++ /dev/null @@ -1,133 +0,0 @@ -import 'package:graphql_schema/graphql_schema.dart'; -import 'package:test/test.dart'; - -import 'common.dart'; - -main() { - test('int', () { - expect(graphQLInt.serialize(23), 23); - }); - - test('float', () { - expect(graphQLFloat.serialize(23.0), 23.0); - }); - - test('bool', () { - expect(graphQLBoolean.serialize(true), true); - }); - - test('string', () { - expect(graphQLString.serialize('a'), 'a'); - }); - - test('enum', () { - var response = enumTypeFromStrings('Response', ['YES', 'NO']); - expect(response.serialize('YES'), 'YES'); - }); - - test('enum only serializes correct values', () { - var response = enumTypeFromStrings('Response', ['YES', 'NO']); - expect(() => response.serialize('MAYBE'), throwsStateError); - }); - - test('date', () { - var now = new DateTime.now(); - expect(graphQLDate.serialize(now), now.toIso8601String()); - }); - - test('list', () { - expect(listOf(graphQLString).serialize(['foo', 'bar']), ['foo', 'bar']); - - var today = new DateTime.now(); - var tomorrow = today.add(new Duration(days: 1)); - expect(listOf(graphQLDate).serialize([today, tomorrow]), - [today.toIso8601String(), tomorrow.toIso8601String()]); - }); - - group('input object', () { - var type = inputObjectType( - 'Foo', - inputFields: [ - inputField('bar', graphQLString.nonNullable()), - inputField('baz', graphQLFloat.nonNullable()), - ], - ); - - test('serializes valid input', () { - expect( - type.serialize({'bar': 'a', 'baz': 2.0}), {'bar': 'a', 'baz': 2.0}); - }); - }); - - test('object', () { - var catchDate = new DateTime.now(); - - var pikachu = {'species': 'Pikachu', 'catch_date': catchDate}; - - expect(pokemonType.serialize(pikachu), - {'species': 'Pikachu', 'catch_date': catchDate.toIso8601String()}); - }); - - test('union type lets any of its types serialize', () { - var typeType = enumTypeFromStrings('Type', [ - 'FIRE', - 'WATER', - 'GRASS', - ]); - - var pokemonType = objectType('Pokémon', fields: [ - field( - 'name', - graphQLString.nonNullable(), - ), - field( - 'type', - typeType, - ), - ]); - - var digimonType = objectType( - 'Digimon', - fields: [ - field('size', graphQLFloat.nonNullable()), - ], - ); - - var u = new GraphQLUnionType('Monster', [pokemonType, digimonType]); - - expect(u.serialize({'size': 10.0}), {'size': 10.0}); - expect(u.serialize({'name': 'Charmander', 'type': 'FIRE'}), - {'name': 'Charmander', 'type': 'FIRE'}); - }); - - test('nested object', () { - var pikachuDate = new DateTime.now(), - charizardDate = pikachuDate.subtract(new Duration(days: 10)); - - var pikachu = {'species': 'Pikachu', 'catch_date': pikachuDate}; - var charizard = {'species': 'Charizard', 'catch_date': charizardDate}; - - var trainer = {'name': 'Tobe O'}; - - var region = pokemonRegionType.serialize({ - 'trainer': trainer, - 'pokemon_species': [pikachu, charizard] - }); - print(region); - - expect(region, { - 'trainer': trainer, - 'pokemon_species': [ - {'species': 'Pikachu', 'catch_date': pikachuDate.toIso8601String()}, - {'species': 'Charizard', 'catch_date': charizardDate.toIso8601String()} - ] - }); - - expect( - () => pokemonRegionType.serialize({ - 'trainer': trainer, - 'DIGIMON_species': [pikachu, charizard] - }), - throwsUnsupportedError); - }); -} diff --git a/packages/graphql/graphql_schema/test/validation_test.dart b/packages/graphql/graphql_schema/test/validation_test.dart deleted file mode 100644 index 32af12c1..00000000 --- a/packages/graphql/graphql_schema/test/validation_test.dart +++ /dev/null @@ -1,102 +0,0 @@ -import 'package:graphql_schema/graphql_schema.dart'; -import 'package:test/test.dart'; - -void main() { - var typeType = enumTypeFromStrings('Type', [ - 'FIRE', - 'WATER', - 'GRASS', - ]); - - var pokemonType = objectType('Pokémon', fields: [ - field( - 'name', - graphQLString.nonNullable(), - ), - field( - 'type', - typeType, - ), - ]); - - var isValidPokemon = predicate( - (x) => - pokemonType.validate('@root', x as Map).successful, - 'is a valid Pokémon'); - - var throwsATypeError = throwsA(predicate( - (x) => x is TypeError || x is CastError, 'is a type or cast error')); - - test('object accepts valid input', () { - expect({'name': 'Charmander', 'type': 'FIRE'}, isValidPokemon); - }); - - test('mismatched scalar type', () { - expect(() => pokemonType.validate('@root', {'name': 24}), throwsATypeError); - }); - - test('empty passed for non-nullable', () { - expect({}, isNot(isValidPokemon)); - }); - - test('null passed for non-nullable', () { - expect({'name': null}, isNot(isValidPokemon)); - }); - - test('rejects extraneous fields', () { - expect({'name': 'Vulpix', 'foo': 'bar'}, isNot(isValidPokemon)); - }); - - test('enum accepts valid value', () { - expect(typeType.validate('@root', 'FIRE').successful, true); - }); - - test('enum rejects invalid value', () { - expect(typeType.validate('@root', 'POISON').successful, false); - }); - - group('union type', () { - var digimonType = objectType( - 'Digimon', - fields: [ - field('size', graphQLFloat.nonNullable()), - ], - ); - - var u = new GraphQLUnionType('Monster', [pokemonType, digimonType]); - - test('any of its types returns valid', () { - expect(u.validate('@root', {'size': 32.0}).successful, true); - expect( - u.validate( - '@root', {'name': 'Charmander', 'type': 'FIRE'}).successful, - true); - }); - }); - - group('input object', () { - var type = inputObjectType( - 'Foo', - inputFields: [ - inputField('bar', graphQLString.nonNullable()), - inputField('baz', graphQLFloat.nonNullable()), - ], - ); - - test('accept valid input', () { - expect(type.validate('@root', {'bar': 'a', 'baz': 2.0}).value, - {'bar': 'a', 'baz': 2.0}); - }); - - test('error on missing non-null fields', () { - expect(type.validate('@root', {'bar': 'a'}).successful, false); - }); - - test('error on unrecognized fields', () { - expect( - type.validate( - '@root', {'bar': 'a', 'baz': 2.0, 'franken': 'stein'}).successful, - false); - }); - }); -} diff --git a/packages/graphql/graphql_server/.gitignore b/packages/graphql/graphql_server/.gitignore deleted file mode 100644 index 26517d3b..00000000 --- a/packages/graphql/graphql_server/.gitignore +++ /dev/null @@ -1,93 +0,0 @@ -# See https://www.dartlang.org/tools/private-files.html - -# Files and directories created by pub -.buildlog -.packages -.project -.pub/ -.scripts-bin/ -build/ -**/packages/ - -# Files created by dart2js -# (Most Dart developers will use pub build to compile Dart, use/modify these -# rules if you intend to use dart2js directly -# Convention is to use extension '.dart.js' for Dart compiled to Javascript to -# differentiate from explicit Javascript files) -*.dart.js -*.part.js -*.js.deps -*.js.map -*.info.json - -# Directory created by dartdoc -doc/api/ - -# Don't commit pubspec lock file -# (Library packages only! Remove pattern if developing an application package) -pubspec.lock -### Dart template -# See https://www.dartlang.org/tools/private-files.html - -# Files and directories created by pub - -# SDK 1.20 and later (no longer creates packages directories) - -# Older SDK versions -# (Include if the minimum SDK version specified in pubsepc.yaml is earlier than 1.20) - - -# Files created by dart2js -# (Most Dart developers will use pub build to compile Dart, use/modify these -# rules if you intend to use dart2js directly -# Convention is to use extension '.dart.js' for Dart compiled to Javascript to -# differentiate from explicit Javascript files) - -# Directory created by dartdoc - -# Don't commit pubspec lock file -# (Library packages only! Remove pattern if developing an application package) -### JetBrains template -# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm -# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 - -# User-specific stuff: -../.idea/workspace.xml -.idea/**/tasks.xml -.idea/dictionaries - -# Sensitive or high-churn files: -.idea/**/dataSources/ -.idea/**/dataSources.ids -.idea/**/dataSources.xml -.idea/**/dataSources.local.xml -.idea/**/sqlDataSources.xml -.idea/**/dynamic.xml -.idea/**/uiDesigner.xml - -# Gradle: -.idea/**/gradle.xml -.idea/**/libraries - -# Mongo Explorer plugin: -.idea/**/mongoSettings.xml - -## File-based project format: -*.iws - -## Plugin-specific files: - -# IntelliJ -/out/ - -# mpeltonen/sbt-idea plugin -.idea_modules/ - -# JIRA plugin -atlassian-ide-plugin.xml - -# Crashlytics plugin (for Android Studio and IntelliJ) -com_crashlytics_export_strings.xml -crashlytics.properties -crashlytics-build.properties -fabric.properties diff --git a/packages/graphql/graphql_server/CHANGELOG.md b/packages/graphql/graphql_server/CHANGELOG.md deleted file mode 100644 index 4bc354ef..00000000 --- a/packages/graphql/graphql_server/CHANGELOG.md +++ /dev/null @@ -1,40 +0,0 @@ -# 1.1.0 -* Updates for `package:graphql_parser@1.2.0`. -* Now that variables are `InputValueContext` descendants, handle them the -same way as other values in `coerceArgumentValues`. TLDR - Removed -now-obsolete, variable-specific logic in `coerceArgumentValues`. -* Pass `argumentName`, not `fieldName`, to type validations. - -# 1.0.3 -* Make field resolution asynchronous. -* Make introspection cycle-safe. -* Thanks @deep-guarav and @micimize! - -# 1.0.2 -* https://github.com/angel-dart/graphql/pull/32 - -# 1.0.1 -* Fix a bug where `globalVariables` were not being properly passed -to field resolvers. - -# 1.0.0 -* Finish testing. -* Add `package:pedantic` fixes. - -# 1.0.0-rc.0 -* Get the Apollo support working with the latest version of `subscriptions-transport-ws`. - -# 1.0.0-beta.4 -For some reason, Pub was not including `subscriptions_transport_ws.dart`. - -# 1.0.0-beta.3 -* Introspection on subscription types (if any). - -# 1.0.0-beta.2 -* Fix bug where field aliases would not be resolved. - -# 1.0.0-beta.1 -* Add (currently untested) subscription support. - -# 1.0.0-beta -* First release. diff --git a/packages/graphql/graphql_server/LICENSE b/packages/graphql/graphql_server/LICENSE deleted file mode 100644 index 89074fd3..00000000 --- a/packages/graphql/graphql_server/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2017 The Angel Framework - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/packages/graphql/graphql_server/README.md b/packages/graphql/graphql_server/README.md deleted file mode 100644 index 2846dc57..00000000 --- a/packages/graphql/graphql_server/README.md +++ /dev/null @@ -1,127 +0,0 @@ -# graphql_server -[![Pub](https://img.shields.io/pub/v/graphql_server.svg)](https://pub.dartlang.org/packages/graphql_server) -[![build status](https://travis-ci.org/angel-dart/graphql.svg)](https://travis-ci.org/angel-dart/graphql) - -Base package for implementing GraphQL servers. -You might prefer [`package:angel_graphql`](https://github.com/angel-dart/graphql), -the fastest way to implement GraphQL backends in Dart. - -`package:graphql_server` does not require any specific -framework, and thus can be used in any Dart project. - -## Ad-hoc Usage -The actual querying functionality is handled by the -`GraphQL` class, which takes a schema (from `package:graphql_schema`). -In most cases, you'll want to call `parseAndExecute` -on some string of GraphQL text. It returns either a `Stream` -or `Map`, and can potentially throw -a `GraphQLException` (which is JSON-serializable): - -```dart -try { - var data = await graphQL.parseExecute(responseText); - - if (data is Stream) { - // Handle a subscription somehow... - } else { - response.send({'data': data}); - } -} on GraphQLException catch(e) { - response.send(e.toJson()); -} -``` - -Consult the API reference for more: -https://pub.dartlang.org/documentation/graphql_server/latest/graphql_server/GraphQL/parseAndExecute.html - -If you're looking for functionality like `graphQLHttp` -in `graphql-js`, that is not included in this package, because -it is typically specific to the framework/platform you are using. -The `graphQLHttp` implementation in `package:angel_graphql` is -a good example: -https://github.com/angel-dart/graphql/blob/master/angel_graphql/lib/src/graphql_http.dart - -## Subscriptions -GraphQL queries involving `subscription` operations can return -a `Stream`. Ultimately, the transport for relaying subscription -events to clients is not specified in the GraphQL spec, so it's -up to you. - -Note that in a schema like this: - -```graphql -type TodoSubscription { - onTodo: TodoAdded! -} - -type TodoAdded { - id: ID! - text: String! - isComplete: Bool -} -``` - -Your Dart schema's resolver for `onTodo` should be -a `Map` *containing an `onTodo` key*: - -```dart -field( - 'onTodo', - todoAddedType, - resolve: (_, __) { - return someStreamOfTodos() - .map((todo) => {'onTodo': todo}); - }, -); -``` - -For the purposes of reusing existing tooling (i.e. JS clients, etc.), -`package:graphql_server` rolls with an implementation of Apollo's -`subscriptions-transport-ws` spec. - -**NOTE: At this point, Apollo's spec is extremely out-of-sync with the protocol their client actually expects.** -**See the following issue to track this:** -**https://github.com/apollographql/subscriptions-transport-ws/issues/551** - -The implementation is built on `package:stream_channel`, and -therefore can be used on any two-way transport, whether it is -WebSockets, TCP sockets, Isolates, or otherwise. - -Users of this package are expected to extend the `Server` -abstract class. `Server` will handle the transport and communication, -but again, ultimately, emitting subscription events is up to your -implementation. - -Here's a snippet from `graphQLWS` in `package:angel_graphql`. -It runs within the context of one single request: - -```dart -var channel = IOWebSocketChannel(socket); -var client = stw.RemoteClient(channel.cast()); -var server = - _GraphQLWSServer(client, graphQL, req, res, keepAliveInterval); -await server.done; -``` - -See `graphQLWS` in `package:angel_graphql` for a good example: -https://github.com/angel-dart/graphql/blob/master/angel_graphql/lib/src/graphql_ws.dart - -## Introspection -Introspection of a GraphQL schema allows clients to query the schema itself, -and get information about the response the server expects. The `GraphQL` -class handles this automatically, so you don't have to write any code for it. - -However, you can call the `reflectSchema` method to manually reflect a schema: -https://pub.dartlang.org/documentation/graphql_server/latest/introspection/reflectSchema.html - -## Mirrors Usage -By default, `dart:mirrors` is not required, but it can be optionally used. - -The `mirrorsFieldResolver` can resolve fields from concrete objects, instead of you -first having to serialize them: -https://pub.dartlang.org/documentation/graphql_server/latest/graphql_server.mirrors/mirrorsFieldResolver.html - -You can also use `convertDartType` to convert a concrete Dart type into a `GraphQLType`. However, -the ideal choice is `package:graphql_generator`. -* https://pub.dartlang.org/documentation/graphql_server/latest/graphql_server.mirrors/convertDartType.html -* https://pub.dartlang.org/packages/graphql_generator \ No newline at end of file diff --git a/packages/graphql/graphql_server/analysis_options.yaml b/packages/graphql/graphql_server/analysis_options.yaml deleted file mode 100644 index c230cee7..00000000 --- a/packages/graphql/graphql_server/analysis_options.yaml +++ /dev/null @@ -1,4 +0,0 @@ -include: package:pedantic/analysis_options.yaml -analyzer: - strong-mode: - implicit-casts: false \ No newline at end of file diff --git a/packages/graphql/graphql_server/example/main.dart b/packages/graphql/graphql_server/example/main.dart deleted file mode 100644 index 335fe284..00000000 --- a/packages/graphql/graphql_server/example/main.dart +++ /dev/null @@ -1,52 +0,0 @@ -import 'package:graphql_schema/graphql_schema.dart'; -import 'package:graphql_server/graphql_server.dart'; -import 'package:test/test.dart'; - -void main() { - test('single element', () async { - var todoType = objectType('todo', fields: [ - field( - 'text', - graphQLString, - resolve: (obj, args) => obj.text, - ), - field( - 'completed', - graphQLBoolean, - resolve: (obj, args) => obj.completed, - ), - ]); - - var schema = graphQLSchema( - queryType: objectType('api', fields: [ - field( - 'todos', - listOf(todoType), - resolve: (_, __) => [ - Todo( - text: 'Clean your room!', - completed: false, - ) - ], - ), - ]), - ); - - var graphql = GraphQL(schema); - var result = await graphql.parseAndExecute('{ todos { text } }'); - - print(result); - expect(result, { - 'todos': [ - {'text': 'Clean your room!'} - ] - }); - }); -} - -class Todo { - final String text; - final bool completed; - - Todo({this.text, this.completed}); -} diff --git a/packages/graphql/graphql_server/graphql_server.iml b/packages/graphql/graphql_server/graphql_server.iml deleted file mode 100644 index 0854fb6e..00000000 --- a/packages/graphql/graphql_server/graphql_server.iml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/packages/graphql/graphql_server/lib/graphql_server.dart b/packages/graphql/graphql_server/lib/graphql_server.dart deleted file mode 100644 index c77e73af..00000000 --- a/packages/graphql/graphql_server/lib/graphql_server.dart +++ /dev/null @@ -1,734 +0,0 @@ -import 'dart:async'; -import 'package:graphql_parser/graphql_parser.dart'; -import 'package:graphql_schema/graphql_schema.dart'; -import 'introspection.dart'; - -/// Transforms any [Map] into `Map`. -Map foldToStringDynamic(Map map) { - return map == null - ? null - : map.keys.fold>( - {}, (out, k) => out..[k.toString()] = map[k]); -} - -/// A Dart implementation of a GraphQL server. -class GraphQL { - /// Any custom types to include in introspection information. - final List customTypes = []; - - /// An optional callback that can be used to resolve fields from objects that are not [Map]s, - /// when the related field has no resolver. - final FutureOr Function(T, String, Map) - defaultFieldResolver; - - GraphQLSchema _schema; - - GraphQL(GraphQLSchema schema, - {bool introspect = true, - this.defaultFieldResolver, - List customTypes = const []}) - : _schema = schema { - if (customTypes?.isNotEmpty == true) { - this.customTypes.addAll(customTypes); - } - - if (introspect) { - var allTypes = fetchAllTypes(schema, [...this.customTypes]); - - _schema = reflectSchema(_schema, allTypes); - - for (var type in allTypes.toSet()) { - if (!this.customTypes.contains(type)) { - this.customTypes.add(type); - } - } - } - - if (_schema.queryType != null) this.customTypes.add(_schema.queryType); - if (_schema.mutationType != null) { - this.customTypes.add(_schema.mutationType); - } - if (_schema.subscriptionType != null) { - this.customTypes.add(_schema.subscriptionType); - } - } - - GraphQLType convertType(TypeContext ctx) { - if (ctx.listType != null) { - return GraphQLListType(convertType(ctx.listType.innerType)); - } else if (ctx.typeName != null) { - switch (ctx.typeName.name) { - case 'Int': - return graphQLInt; - case 'Float': - return graphQLFloat; - case 'String': - return graphQLString; - case 'Boolean': - return graphQLBoolean; - case 'ID': - return graphQLId; - case 'Date': - case 'DateTime': - return graphQLDate; - default: - return customTypes.firstWhere((t) => t.name == ctx.typeName.name, - orElse: () => throw ArgumentError( - 'Unknown GraphQL type: "${ctx.typeName.name}"')); - } - } else { - throw ArgumentError('Invalid GraphQL type: "${ctx.span.text}"'); - } - } - - Future parseAndExecute(String text, - {String operationName, - sourceUrl, - Map variableValues = const {}, - initialValue, - Map globalVariables}) { - var tokens = scan(text, sourceUrl: sourceUrl); - var parser = Parser(tokens); - var document = parser.parseDocument(); - - if (parser.errors.isNotEmpty) { - throw GraphQLException(parser.errors - .map((e) => GraphQLExceptionError(e.message, locations: [ - GraphExceptionErrorLocation.fromSourceLocation(e.span.start) - ])) - .toList()); - } - - return executeRequest( - _schema, - document, - operationName: operationName, - initialValue: initialValue, - variableValues: variableValues, - globalVariables: globalVariables, - ); - } - - Future executeRequest(GraphQLSchema schema, DocumentContext document, - {String operationName, - Map variableValues = const {}, - initialValue, - Map globalVariables = const {}}) async { - var operation = getOperation(document, operationName); - var coercedVariableValues = coerceVariableValues( - schema, operation, variableValues ?? {}); - if (operation.isQuery) { - return await executeQuery(document, operation, schema, - coercedVariableValues, initialValue, globalVariables); - } else if (operation.isSubscription) { - return await subscribe(document, operation, schema, coercedVariableValues, - globalVariables, initialValue); - } else { - return executeMutation(document, operation, schema, coercedVariableValues, - initialValue, globalVariables); - } - } - - OperationDefinitionContext getOperation( - DocumentContext document, String operationName) { - var ops = document.definitions.whereType(); - - if (operationName == null) { - return ops.length == 1 - ? ops.first - : throw GraphQLException.fromMessage( - 'This document does not define any operations.'); - } else { - return ops.firstWhere((d) => d.name == operationName, - orElse: () => throw GraphQLException.fromMessage( - 'Missing required operation "$operationName".')); - } - } - - Map coerceVariableValues( - GraphQLSchema schema, - OperationDefinitionContext operation, - Map variableValues) { - var coercedValues = {}; - var variableDefinitions = - operation.variableDefinitions?.variableDefinitions ?? []; - - for (var variableDefinition in variableDefinitions) { - var variableName = variableDefinition.variable.name; - var variableType = variableDefinition.type; - var defaultValue = variableDefinition.defaultValue; - var value = variableValues[variableName]; - - if (value == null) { - if (defaultValue != null) { - coercedValues[variableName] = - defaultValue.value.computeValue(variableValues); - } else if (!variableType.isNullable) { - throw GraphQLException.fromSourceSpan( - 'Missing required variable "$variableName".', - variableDefinition.span); - } - } else { - var type = convertType(variableType); - var validation = type.validate(variableName, value); - - if (!validation.successful) { - throw GraphQLException(validation.errors - .map((e) => GraphQLExceptionError(e, locations: [ - GraphExceptionErrorLocation.fromSourceLocation( - variableDefinition.span.start) - ])) - .toList()); - } else { - coercedValues[variableName] = type.deserialize(value); - } - } - } - - return coercedValues; - } - - Future> executeQuery( - DocumentContext document, - OperationDefinitionContext query, - GraphQLSchema schema, - Map variableValues, - initialValue, - Map globalVariables) async { - var queryType = schema.queryType; - var selectionSet = query.selectionSet; - return await executeSelectionSet(document, selectionSet, queryType, - initialValue, variableValues, globalVariables); - } - - Future> executeMutation( - DocumentContext document, - OperationDefinitionContext mutation, - GraphQLSchema schema, - Map variableValues, - initialValue, - Map globalVariables) async { - var mutationType = schema.mutationType; - - if (mutationType == null) { - throw GraphQLException.fromMessage( - 'The schema does not define a mutation type.'); - } - - var selectionSet = mutation.selectionSet; - return await executeSelectionSet(document, selectionSet, mutationType, - initialValue, variableValues, globalVariables); - } - - Future>> subscribe( - DocumentContext document, - OperationDefinitionContext subscription, - GraphQLSchema schema, - Map variableValues, - Map globalVariables, - initialValue) async { - var sourceStream = await createSourceEventStream( - document, subscription, schema, variableValues, initialValue); - return mapSourceToResponseEvent(sourceStream, subscription, schema, - document, initialValue, variableValues, globalVariables); - } - - Future createSourceEventStream( - DocumentContext document, - OperationDefinitionContext subscription, - GraphQLSchema schema, - Map variableValues, - initialValue) { - var selectionSet = subscription.selectionSet; - var subscriptionType = schema.subscriptionType; - if (subscriptionType == null) { - throw GraphQLException.fromSourceSpan( - 'The schema does not define a subscription type.', subscription.span); - } - var groupedFieldSet = - collectFields(document, subscriptionType, selectionSet, variableValues); - if (groupedFieldSet.length != 1) { - throw GraphQLException.fromSourceSpan( - 'The grouped field set from this query must have exactly one entry.', - selectionSet.span); - } - var fields = groupedFieldSet.entries.first.value; - var fieldName = fields.first.field.fieldName.alias?.name ?? - fields.first.field.fieldName.name; - var field = fields.first; - var argumentValues = - coerceArgumentValues(subscriptionType, field, variableValues); - return resolveFieldEventStream( - subscriptionType, initialValue, fieldName, argumentValues); - } - - Stream> mapSourceToResponseEvent( - Stream sourceStream, - OperationDefinitionContext subscription, - GraphQLSchema schema, - DocumentContext document, - initialValue, - Map variableValues, - Map globalVariables, - ) async* { - await for (var event in sourceStream) { - yield await executeSubscriptionEvent(document, subscription, schema, - event, variableValues, globalVariables); - } - } - - Future> executeSubscriptionEvent( - DocumentContext document, - OperationDefinitionContext subscription, - GraphQLSchema schema, - initialValue, - Map variableValues, - Map globalVariables) async { - var selectionSet = subscription.selectionSet; - var subscriptionType = schema.subscriptionType; - if (subscriptionType == null) { - throw GraphQLException.fromSourceSpan( - 'The schema does not define a subscription type.', subscription.span); - } - try { - var data = await executeSelectionSet(document, selectionSet, - subscriptionType, initialValue, variableValues, globalVariables); - return {'data': data}; - } on GraphQLException catch (e) { - return { - 'data': null, - 'errors': [e.errors.map((e) => e.toJson()).toList()] - }; - } - } - - Future resolveFieldEventStream(GraphQLObjectType subscriptionType, - rootValue, String fieldName, Map argumentValues) async { - var field = subscriptionType.fields.firstWhere((f) => f.name == fieldName, - orElse: () { - throw GraphQLException.fromMessage( - 'No subscription field named "$fieldName" is defined.'); - }); - var resolver = field.resolve; - var result = await resolver(rootValue, argumentValues); - if (result is Stream) { - return result; - } else { - return Stream.fromIterable([result]); - } - } - - Future> executeSelectionSet( - DocumentContext document, - SelectionSetContext selectionSet, - GraphQLObjectType objectType, - objectValue, - Map variableValues, - Map globalVariables) async { - var groupedFieldSet = - collectFields(document, objectType, selectionSet, variableValues); - var resultMap = {}; - var futureResultMap = >{}; - - for (var responseKey in groupedFieldSet.keys) { - var fields = groupedFieldSet[responseKey]; - for (var field in fields) { - var fieldName = - field.field.fieldName.alias?.name ?? field.field.fieldName.name; - FutureOr futureResponseValue; - - if (fieldName == '__typename') { - futureResponseValue = objectType.name; - } else { - var fieldType = objectType.fields - .firstWhere((f) => f.name == fieldName, orElse: () => null) - ?.type; - if (fieldType == null) continue; - futureResponseValue = executeField( - document, - fieldName, - objectType, - objectValue, - fields, - fieldType, - Map.from(globalVariables ?? {}) - ..addAll(variableValues), - globalVariables); - } - - futureResultMap[responseKey] = futureResponseValue; - } - } - for (var f in futureResultMap.keys) { - resultMap[f] = await futureResultMap[f]; - } - return resultMap; - } - - Future executeField( - DocumentContext document, - String fieldName, - GraphQLObjectType objectType, - objectValue, - List fields, - GraphQLType fieldType, - Map variableValues, - Map globalVariables) async { - var field = fields[0]; - var argumentValues = - coerceArgumentValues(objectType, field, variableValues); - var resolvedValue = await resolveFieldValue( - objectType, - objectValue, - fieldName, - Map.from(globalVariables ?? {}) - ..addAll(argumentValues ?? {})); - return completeValue(document, fieldName, fieldType, fields, resolvedValue, - variableValues, globalVariables); - } - - Map coerceArgumentValues(GraphQLObjectType objectType, - SelectionContext field, Map variableValues) { - var coercedValues = {}; - var argumentValues = field.field.arguments; - var fieldName = - field.field.fieldName.alias?.name ?? field.field.fieldName.name; - var desiredField = objectType.fields.firstWhere((f) => f.name == fieldName, - orElse: () => throw FormatException( - '${objectType.name} has no field named "$fieldName".')); - var argumentDefinitions = desiredField.inputs; - - for (var argumentDefinition in argumentDefinitions) { - var argumentName = argumentDefinition.name; - var argumentType = argumentDefinition.type; - var defaultValue = argumentDefinition.defaultValue; - - var argumentValue = argumentValues - .firstWhere((a) => a.name == argumentName, orElse: () => null); - - if (argumentValue == null) { - if (defaultValue != null || argumentDefinition.defaultsToNull) { - coercedValues[argumentName] = defaultValue; - } else if (argumentType is GraphQLNonNullableType) { - throw GraphQLException.fromMessage( - 'Missing value for argument "$argumentName" of field "$fieldName".'); - } else { - continue; - } - } else { - try { - var validation = argumentType.validate( - argumentName, argumentValue.value.computeValue(variableValues)); - - if (!validation.successful) { - var errors = [ - GraphQLExceptionError( - 'Type coercion error for value of argument "$argumentName" of field "$fieldName".', - locations: [ - GraphExceptionErrorLocation.fromSourceLocation( - argumentValue.value.span.start) - ], - ) - ]; - - for (var error in validation.errors) { - errors.add( - GraphQLExceptionError( - error, - locations: [ - GraphExceptionErrorLocation.fromSourceLocation( - argumentValue.value.span.start) - ], - ), - ); - } - - throw GraphQLException(errors); - } else { - var coercedValue = validation.value; - coercedValues[argumentName] = coercedValue; - } - } on TypeError catch (e) { - throw GraphQLException([ - GraphQLExceptionError( - 'Type coercion error for value of argument "$argumentName" of field "$fieldName".', - locations: [ - GraphExceptionErrorLocation.fromSourceLocation( - argumentValue.value.span.start) - ], - ), - GraphQLExceptionError( - e.toString(), - locations: [ - GraphExceptionErrorLocation.fromSourceLocation( - argumentValue.value.span.start) - ], - ), - ]); - } - } - } - - return coercedValues; - } - - Future resolveFieldValue(GraphQLObjectType objectType, T objectValue, - String fieldName, Map argumentValues) async { - var field = objectType.fields.firstWhere((f) => f.name == fieldName); - - if (objectValue is Map) { - return objectValue[fieldName] as T; - } else if (field.resolve == null) { - if (defaultFieldResolver != null) { - return await defaultFieldResolver( - objectValue, fieldName, argumentValues); - } - - return null; - } else { - return await field.resolve(objectValue, argumentValues) as T; - } - } - - Future completeValue( - DocumentContext document, - String fieldName, - GraphQLType fieldType, - List fields, - result, - Map variableValues, - Map globalVariables) async { - if (fieldType is GraphQLNonNullableType) { - var innerType = fieldType.ofType; - var completedResult = await completeValue(document, fieldName, innerType, - fields, result, variableValues, globalVariables); - - if (completedResult == null) { - throw GraphQLException.fromMessage( - 'Null value provided for non-nullable field "$fieldName".'); - } else { - return completedResult; - } - } - - if (result == null) { - return null; - } - - if (fieldType is GraphQLListType) { - if (result is! Iterable) { - throw GraphQLException.fromMessage( - 'Value of field "$fieldName" must be a list or iterable, got $result instead.'); - } - - var innerType = fieldType.ofType; - var futureOut = []; - - for (var resultItem in (result as Iterable)) { - futureOut.add(completeValue(document, '(item in "$fieldName")', - innerType, fields, resultItem, variableValues, globalVariables)); - } - - var out = []; - for (var f in futureOut) { - out.add(await f); - } - - return out; - } - - if (fieldType is GraphQLScalarType) { - try { - var validation = fieldType.validate(fieldName, result); - - if (!validation.successful) { - return null; - } else { - return validation.value; - } - } on TypeError { - throw GraphQLException.fromMessage( - 'Value of field "$fieldName" must be ${fieldType.valueType}, got $result instead.'); - } - } - - if (fieldType is GraphQLObjectType || fieldType is GraphQLUnionType) { - GraphQLObjectType objectType; - - if (fieldType is GraphQLObjectType && !fieldType.isInterface) { - objectType = fieldType; - } else { - objectType = resolveAbstractType(fieldName, fieldType, result); - } - - var subSelectionSet = mergeSelectionSets(fields); - return await executeSelectionSet(document, subSelectionSet, objectType, - result, variableValues, globalVariables); - } - - throw UnsupportedError('Unsupported type: $fieldType'); - } - - GraphQLObjectType resolveAbstractType( - String fieldName, GraphQLType type, result) { - List possibleTypes; - - if (type is GraphQLObjectType) { - if (type.isInterface) { - possibleTypes = type.possibleTypes; - } else { - return type; - } - } else if (type is GraphQLUnionType) { - possibleTypes = type.possibleTypes; - } else { - throw ArgumentError(); - } - - var errors = []; - - for (var t in possibleTypes) { - try { - var validation = - t.validate(fieldName, foldToStringDynamic(result as Map)); - - if (validation.successful) { - return t; - } - - errors.addAll(validation.errors.map((m) => GraphQLExceptionError(m))); - } on GraphQLException catch (e) { - errors.addAll(e.errors); - } - } - - errors.insert(0, - GraphQLExceptionError('Cannot convert value $result to type $type.')); - - throw GraphQLException(errors); - } - - SelectionSetContext mergeSelectionSets(List fields) { - var selections = []; - - for (var field in fields) { - if (field.field?.selectionSet != null) { - selections.addAll(field.field.selectionSet.selections); - } else if (field.inlineFragment?.selectionSet != null) { - selections.addAll(field.inlineFragment.selectionSet.selections); - } - } - - return SelectionSetContext.merged(selections); - } - - Map> collectFields( - DocumentContext document, - GraphQLObjectType objectType, - SelectionSetContext selectionSet, - Map variableValues, - {List visitedFragments}) { - var groupedFields = >{}; - visitedFragments ??= []; - - for (var selection in selectionSet.selections) { - if (getDirectiveValue('skip', 'if', selection, variableValues) == true) { - continue; - } - if (getDirectiveValue('include', 'if', selection, variableValues) == - false) { - continue; - } - - if (selection.field != null) { - var responseKey = selection.field.fieldName.alias?.alias ?? - selection.field.fieldName.name; - var groupForResponseKey = - groupedFields.putIfAbsent(responseKey, () => []); - groupForResponseKey.add(selection); - } else if (selection.fragmentSpread != null) { - var fragmentSpreadName = selection.fragmentSpread.name; - if (visitedFragments.contains(fragmentSpreadName)) continue; - visitedFragments.add(fragmentSpreadName); - var fragment = document.definitions - .whereType() - .firstWhere((f) => f.name == fragmentSpreadName, - orElse: () => null); - - if (fragment == null) continue; - var fragmentType = fragment.typeCondition; - if (!doesFragmentTypeApply(objectType, fragmentType)) continue; - var fragmentSelectionSet = fragment.selectionSet; - var fragmentGroupFieldSet = collectFields( - document, objectType, fragmentSelectionSet, variableValues); - - for (var responseKey in fragmentGroupFieldSet.keys) { - var fragmentGroup = fragmentGroupFieldSet[responseKey]; - var groupForResponseKey = - groupedFields.putIfAbsent(responseKey, () => []); - groupForResponseKey.addAll(fragmentGroup); - } - } else if (selection.inlineFragment != null) { - var fragmentType = selection.inlineFragment.typeCondition; - if (fragmentType != null && - !doesFragmentTypeApply(objectType, fragmentType)) continue; - var fragmentSelectionSet = selection.inlineFragment.selectionSet; - var fragmentGroupFieldSet = collectFields( - document, objectType, fragmentSelectionSet, variableValues); - - for (var responseKey in fragmentGroupFieldSet.keys) { - var fragmentGroup = fragmentGroupFieldSet[responseKey]; - var groupForResponseKey = - groupedFields.putIfAbsent(responseKey, () => []); - groupForResponseKey.addAll(fragmentGroup); - } - } - } - - return groupedFields; - } - - getDirectiveValue(String name, String argumentName, - SelectionContext selection, Map variableValues) { - if (selection.field == null) return null; - var directive = selection.field.directives.firstWhere((d) { - var vv = d.value; - if (vv is VariableContext) { - return vv.name == name; - } else { - return vv.computeValue(variableValues) == name; - } - }, orElse: () => null); - - if (directive == null) return null; - if (directive.argument?.name != argumentName) return null; - - var vv = directive.argument.value; - if (vv is VariableContext) { - var vname = vv.name; - if (!variableValues.containsKey(vname)) { - throw GraphQLException.fromSourceSpan( - 'Unknown variable: "$vname"', vv.span); - } - return variableValues[vname]; - } - return vv.computeValue(variableValues); - } - - bool doesFragmentTypeApply( - GraphQLObjectType objectType, TypeConditionContext fragmentType) { - var type = convertType(TypeContext(fragmentType.typeName, null)); - if (type is GraphQLObjectType && !type.isInterface) { - for (var field in type.fields) { - if (!objectType.fields.any((f) => f.name == field.name)) return false; - } - return true; - } else if (type is GraphQLObjectType && type.isInterface) { - return objectType.isImplementationOf(type); - } else if (type is GraphQLUnionType) { - return type.possibleTypes.any((t) => objectType.isImplementationOf(t)); - } - - return false; - } -} diff --git a/packages/graphql/graphql_server/lib/introspection.dart b/packages/graphql/graphql_server/lib/introspection.dart deleted file mode 100644 index bb755754..00000000 --- a/packages/graphql/graphql_server/lib/introspection.dart +++ /dev/null @@ -1,528 +0,0 @@ -import 'package:graphql_parser/graphql_parser.dart'; -import 'package:graphql_schema/graphql_schema.dart'; - -/// Performs introspection over a GraphQL [schema], and returns a one, containing -/// introspective information. -/// -/// [allTypes] should contain all types, not directly defined in the schema, that you -/// would like to have introspection available for. -GraphQLSchema reflectSchema(GraphQLSchema schema, List allTypes) { - var typeType = _reflectSchemaTypes(); - var directiveType = _reflectDirectiveType(); - - Set allTypeSet; - - var schemaType = objectType('__Schema', fields: [ - field( - 'types', - listOf(typeType), - resolve: (_, __) => allTypeSet ??= allTypes.toSet(), - ), - field( - 'queryType', - typeType, - resolve: (_, __) => schema.queryType, - ), - field( - 'mutationType', - typeType, - resolve: (_, __) => schema.mutationType, - ), - field( - 'subscriptionType', - typeType, - resolve: (_, __) => schema.subscriptionType, - ), - field( - 'directives', - listOf(directiveType).nonNullable(), - resolve: (_, __) => [], // TODO: Actually fetch directives - ), - ]); - - allTypes.addAll([ - graphQLBoolean, - graphQLString, - graphQLId, - graphQLDate, - graphQLFloat, - graphQLInt, - directiveType, - typeType, - directiveType, - schemaType, - _typeKindType, - _directiveLocationType, - _reflectFields(), - _reflectInputValueType(), - _reflectEnumValueType(), - ]); - - var fields = [ - field( - '__schema', - schemaType, - resolve: (_, __) => schemaType, - ), - field( - '__type', - typeType, - inputs: [GraphQLFieldInput('name', graphQLString.nonNullable())], - resolve: (_, args) { - var name = args['name'] as String; - return allTypes.firstWhere((t) => t.name == name, - orElse: () => throw GraphQLException.fromMessage( - 'No type named "$name" exists.')); - }, - ), - ]; - - fields.addAll(schema.queryType.fields); - - return GraphQLSchema( - queryType: objectType(schema.queryType.name, fields: fields), - mutationType: schema.mutationType, - subscriptionType: schema.subscriptionType, - ); -} - -GraphQLObjectType _typeType; - -GraphQLObjectType _reflectSchemaTypes() { - if (_typeType == null) { - _typeType = _createTypeType(); - _typeType.fields.add( - field( - 'ofType', - _reflectSchemaTypes(), - resolve: (type, _) { - if (type is GraphQLListType) - return type.ofType; - else if (type is GraphQLNonNullableType) return type.ofType; - return null; - }, - ), - ); - - _typeType.fields.add( - field( - 'interfaces', - listOf(_reflectSchemaTypes().nonNullable()), - resolve: (type, _) { - if (type is GraphQLObjectType) { - return type.interfaces; - } else { - return []; - } - }, - ), - ); - - _typeType.fields.add( - field( - 'possibleTypes', - listOf(_reflectSchemaTypes().nonNullable()), - resolve: (type, _) { - if (type is GraphQLObjectType && type.isInterface) { - return type.possibleTypes; - } else if (type is GraphQLUnionType) { - return type.possibleTypes; - } else { - return null; - } - }, - ), - ); - - var fieldType = _reflectFields(); - var inputValueType = _reflectInputValueType(); - var typeField = fieldType.fields - .firstWhere((f) => f.name == 'type', orElse: () => null); - - if (typeField == null) { - fieldType.fields.add( - field( - 'type', - _reflectSchemaTypes(), - resolve: (f, _) => (f as GraphQLObjectField).type, - ), - ); - } - - typeField = inputValueType.fields - .firstWhere((f) => f.name == 'type', orElse: () => null); - - if (typeField == null) { - inputValueType.fields.add( - field( - 'type', - _reflectSchemaTypes(), - resolve: (f, _) => - _fetchFromInputValue(f, (f) => f.type, (f) => f.type), - ), - ); - } - } - - return _typeType; -} - -final GraphQLEnumType _typeKindType = - enumTypeFromStrings('__TypeKind', [ - 'SCALAR', - 'OBJECT', - 'INTERFACE', - 'UNION', - 'ENUM', - 'INPUT_OBJECT', - 'LIST', - 'NON_NULL' -]); - -GraphQLObjectType _createTypeType() { - var enumValueType = _reflectEnumValueType(); - var fieldType = _reflectFields(); - var inputValueType = _reflectInputValueType(); - - return objectType('__Type', fields: [ - field( - 'name', - graphQLString, - resolve: (type, _) => (type as GraphQLType).name, - ), - field( - 'description', - graphQLString, - resolve: (type, _) => (type as GraphQLType).description, - ), - field( - 'kind', - _typeKindType, - resolve: (type, _) { - var t = type as GraphQLType; - - if (t is GraphQLEnumType) { - return 'ENUM'; - } else if (t is GraphQLScalarType) { - return 'SCALAR'; - } else if (t is GraphQLInputObjectType) { - return 'INPUT_OBJECT'; - } else if (t is GraphQLObjectType) { - return t.isInterface ? 'INTERFACE' : 'OBJECT'; - } else if (t is GraphQLListType) { - return 'LIST'; - } else if (t is GraphQLNonNullableType) { - return 'NON_NULL'; - } else if (t is GraphQLUnionType) { - return 'UNION'; - } else { - throw UnsupportedError('Cannot get the kind of $t.'); - } - }, - ), - field( - 'fields', - listOf(fieldType), - inputs: [ - new GraphQLFieldInput( - 'includeDeprecated', - graphQLBoolean, - defaultValue: false, - ), - ], - resolve: (type, args) => type is GraphQLObjectType - ? type.fields - .where( - (f) => !f.isDeprecated || args['includeDeprecated'] == true) - .toList() - : null, - ), - field( - 'enumValues', - listOf(enumValueType.nonNullable()), - inputs: [ - new GraphQLFieldInput( - 'includeDeprecated', - graphQLBoolean, - defaultValue: false, - ), - ], - resolve: (obj, args) { - if (obj is GraphQLEnumType) { - return obj.values - .where( - (f) => !f.isDeprecated || args['includeDeprecated'] == true) - .toList(); - } else { - return null; - } - }, - ), - field( - 'inputFields', - listOf(inputValueType.nonNullable()), - resolve: (obj, _) { - if (obj is GraphQLInputObjectType) { - return obj.inputFields; - } - - return null; - }, - ), - ]); -} - -GraphQLObjectType _fieldType; - -GraphQLObjectType _reflectFields() { - if (_fieldType == null) { - _fieldType = _createFieldType(); - } - - return _fieldType; -} - -GraphQLObjectType _createFieldType() { - var inputValueType = _reflectInputValueType(); - - return objectType('__Field', fields: [ - field( - 'name', - graphQLString, - resolve: (f, _) => (f as GraphQLObjectField).name, - ), - field( - 'description', - graphQLString, - resolve: (f, _) => (f as GraphQLObjectField).description, - ), - field( - 'isDeprecated', - graphQLBoolean, - resolve: (f, _) => (f as GraphQLObjectField).isDeprecated, - ), - field( - 'deprecationReason', - graphQLString, - resolve: (f, _) => (f as GraphQLObjectField).deprecationReason, - ), - field( - 'args', - listOf(inputValueType.nonNullable()).nonNullable(), - resolve: (f, _) => (f as GraphQLObjectField).inputs, - ), - ]); -} - -GraphQLObjectType _inputValueType; - -T _fetchFromInputValue(x, T Function(GraphQLFieldInput) ifInput, - T Function(GraphQLInputObjectField) ifObjectField) { - if (x is GraphQLFieldInput) { - return ifInput(x); - } else if (x is GraphQLInputObjectField) { - return ifObjectField(x); - } else { - return null; - } -} - -GraphQLObjectType _reflectInputValueType() { - return _inputValueType ??= objectType('__InputValue', fields: [ - field( - 'name', - graphQLString.nonNullable(), - resolve: (obj, _) => - _fetchFromInputValue(obj, (f) => f.name, (f) => f.name), - ), - field( - 'description', - graphQLString, - resolve: (obj, _) => - _fetchFromInputValue(obj, (f) => f.description, (f) => f.description), - ), - field( - 'defaultValue', - graphQLString, - resolve: (obj, _) => _fetchFromInputValue(obj, - (f) => f.defaultValue?.toString(), (f) => f.defaultValue?.toString()), - ), - ]); -} - -GraphQLObjectType _directiveType; - -final GraphQLEnumType _directiveLocationType = - enumTypeFromStrings('__DirectiveLocation', [ - 'QUERY', - 'MUTATION', - 'FIELD', - 'FRAGMENT_DEFINITION', - 'FRAGMENT_SPREAD', - 'INLINE_FRAGMENT' -]); - -GraphQLObjectType _reflectDirectiveType() { - var inputValueType = _reflectInputValueType(); - - // TODO: What actually is this??? - return _directiveType ??= objectType('__Directive', fields: [ - field( - 'name', - graphQLString.nonNullable(), - resolve: (obj, _) => (obj as DirectiveContext).nameToken.span.text, - ), - field( - 'description', - graphQLString, - resolve: (obj, _) => null, - ), - field( - 'locations', - listOf(_directiveLocationType.nonNullable()).nonNullable(), - // TODO: Fetch directiveLocation - resolve: (obj, _) => [], - ), - field( - 'args', - listOf(inputValueType.nonNullable()).nonNullable(), - resolve: (obj, _) => [], - ), - ]); -} - -GraphQLObjectType _enumValueType; - -GraphQLObjectType _reflectEnumValueType() { - return _enumValueType ??= objectType( - '__EnumValue', - fields: [ - field( - 'name', - graphQLString.nonNullable(), - resolve: (obj, _) => (obj as GraphQLEnumValue).name, - ), - field( - 'description', - graphQLString, - resolve: (obj, _) => (obj as GraphQLEnumValue).description, - ), - field( - 'isDeprecated', - graphQLBoolean.nonNullable(), - resolve: (obj, _) => (obj as GraphQLEnumValue).isDeprecated, - ), - field( - 'deprecationReason', - graphQLString, - resolve: (obj, _) => (obj as GraphQLEnumValue).deprecationReason, - ), - ], - ); -} - -List fetchAllTypes( - GraphQLSchema schema, List specifiedTypes) { - var data = Set() - ..add(schema.queryType) - ..addAll(specifiedTypes); - - if (schema.mutationType != null) { - data.add(schema.mutationType); - } - - if (schema.subscriptionType != null) { - data.add(schema.subscriptionType); - } - - return CollectTypes(data).types.toList(); -} - -class CollectTypes { - Set traversedTypes = {}; - - Set get types => traversedTypes; - - CollectTypes(Iterable types) { - types.forEach(_fetchAllTypesFromType); - } - - CollectTypes.fromRootObject(GraphQLObjectType type) { - _fetchAllTypesFromObject(type); - } - - void _fetchAllTypesFromObject(GraphQLObjectType objectType) { - if (traversedTypes.contains(objectType)) { - return null; - } - - traversedTypes.add(objectType); - - for (var field in objectType.fields) { - if (field.type is GraphQLObjectType) { - _fetchAllTypesFromObject(field.type as GraphQLObjectType); - } else if (field.type is GraphQLInputObjectType) { - for (var v in (field.type as GraphQLInputObjectType).inputFields) { - _fetchAllTypesFromType(v.type); - } - } else { - _fetchAllTypesFromType(field.type); - } - - for (var input in field.inputs ?? []) { - _fetchAllTypesFromType(input.type); - } - } - - for (var i in objectType.interfaces) { - _fetchAllTypesFromObject(i); - } - } - - void _fetchAllTypesFromType(GraphQLType type) { - if (traversedTypes.contains(type)) { - return null; - } - - /* - * Unwrap generics - */ - if (type is GraphQLNonNullableType) { - return _fetchAllTypesFromType(type.ofType); - } - if (type is GraphQLListType) { - return _fetchAllTypesFromType(type.ofType); - } - - /* - * Handle simple types - */ - if (type is GraphQLEnumType) { - traversedTypes.add(type); - return null; - } - if (type is GraphQLUnionType) { - traversedTypes.add(type); - for (var t in type.possibleTypes) { - _fetchAllTypesFromType(t); - } - return null; - } - if (type is GraphQLInputObjectType) { - traversedTypes.add(type); - for (var v in type.inputFields) { - _fetchAllTypesFromType(v.type); - } - return null; - } - - /* - * defer to object type traverser - */ - if (type is GraphQLObjectType) { - return _fetchAllTypesFromObject(type); - } - - return null; - } -} diff --git a/packages/graphql/graphql_server/lib/mirrors.dart b/packages/graphql/graphql_server/lib/mirrors.dart deleted file mode 100644 index c69589e1..00000000 --- a/packages/graphql/graphql_server/lib/mirrors.dart +++ /dev/null @@ -1,367 +0,0 @@ -// ignore_for_file: deprecated_member_use_from_same_package -import 'dart:mirrors'; -import 'package:angel_serialize/angel_serialize.dart'; -import 'package:graphql_schema/graphql_schema.dart'; -import 'package:recase/recase.dart'; - -/// Uses `dart:mirrors` to read field names from items. If they are Maps, performs a regular lookup. -T mirrorsFieldResolver(objectValue, String fieldName, - [Map objectValues]) { - if (objectValue is Map) { - return objectValue[fieldName] as T; - } else { - return reflect(objectValue).getField(Symbol(fieldName)).reflectee as T; - } -} - -/// Reflects upon a given [type] and dynamically generates a [GraphQLType] that corresponds to it. -/// -/// This function is aware of the annotations from `package:angel_serialize`, and works seamlessly -/// with them. -@deprecated -GraphQLType convertDartType(Type type, [List typeArguments]) { - if (_cache[type] != null) { - return _cache[type]; - } else { - return _objectTypeFromDartType(type, typeArguments); - } -} - -/// Shorthand for [convertDartType], for when you know the result will be an object type. -@deprecated -GraphQLObjectType convertDartClass(Type type, [List typeArguments]) { - return convertDartType(type, typeArguments) as GraphQLObjectType; -} - -final Map _cache = {}; - -GraphQLType _objectTypeFromDartType(Type type, [List typeArguments]) { - if (type == bool) { - return graphQLBoolean; - } else if (type == int) { - return graphQLInt; - } else if (type == double) { - return graphQLFloat; - } else if (type == num) { - throw UnsupportedError( - 'Cannot convert `num` to a GraphQL type. Choose `int` or `float` instead.'); - } else if (type == Null) { - throw UnsupportedError('Cannot convert `Null` to a GraphQL type.'); - } else if (type == String) { - return graphQLString; - } else if (type == DateTime) { - return graphQLDate; - } - - var mirror = reflectType( - type, typeArguments?.isNotEmpty == true ? typeArguments : null); - - if (mirror is! ClassMirror) { - throw StateError( - '$type is not a class, and therefore cannot be converted into a GraphQL object type.'); - } - - var clazz = mirror as ClassMirror; - - if (clazz.isAssignableTo(reflectType(Iterable))) { - if (clazz.typeArguments.isNotEmpty) { - var inner = convertDartType(clazz.typeArguments[0].reflectedType); - //if (inner == null) return null; - return listOf(inner.nonNullable()); - } - - throw ArgumentError( - 'Cannot convert ${clazz.reflectedType}, an iterable WITHOUT a type argument, into a GraphQL type.'); - } - - if (clazz.isEnum) { - return enumTypeFromClassMirror(clazz); - } - - return objectTypeFromClassMirror(clazz); -} - -@deprecated -GraphQLObjectType objectTypeFromClassMirror(ClassMirror mirror) { - if (_cache[mirror.reflectedType] != null) { - return _cache[mirror.reflectedType] as GraphQLObjectType; - } else {} - - var fields = []; - var ready = {}; - var forward = {}; - - void walkMap(Map map) { - for (var name in map.keys) { - var methodMirror = map[name]; - var exclude = _getExclude(name, methodMirror); - var canAdd = name != #hashCode && - name != #runtimeType && - !methodMirror.isPrivate && - exclude?.canSerialize != true; - - if (methodMirror.isGetter && canAdd) { - fields.add(fieldFromGetter(name, methodMirror, exclude, mirror)); - } - } - } - - bool isReady(TypeMirror returnType) { - var canContinue = returnType.reflectedType != mirror.reflectedType; - - if (canContinue && - returnType.isAssignableTo(reflectType(Iterable)) && - returnType.typeArguments.isNotEmpty && - !isReady(returnType.typeArguments[0])) { - canContinue = false; - } - - return canContinue; - } - - void prepReadyForward(Map map) { - map.forEach((name, methodMirror) { - if (methodMirror.isGetter && - name != #_identityHashCode && - name != #runtimeType && - name != #hashCode && - MirrorSystem.getName(name) != '_identityHashCode') { - var returnType = methodMirror.returnType; - - if (isReady(returnType)) { - ready[name] = methodMirror; - } else { - forward[name] = methodMirror; - } - } - }); - } - - prepReadyForward(mirror.instanceMembers); - - walkMap(ready); - - if (mirror.isAbstract) { - var decls = {}; - - mirror.declarations.forEach((name, decl) { - if (decl is MethodMirror) { - decls[name] = decl; - } - }); - - ready.clear(); - forward.clear(); - prepReadyForward(decls); - walkMap(ready); - //walkMap(decls); - } - - var inheritsFrom = []; - var primitiveTypes = const [ - String, - bool, - num, - int, - double, - Object, - dynamic, - Null, - Type, - Symbol - ]; - - void walk(ClassMirror parent) { - if (!primitiveTypes.contains(parent.reflectedType)) { - if (parent.isAbstract) { - var obj = convertDartType(parent.reflectedType); - - if (obj is GraphQLObjectType && !inheritsFrom.contains(obj)) { - inheritsFrom.add(obj); - } - } - - walk(parent.superclass); - parent.superinterfaces.forEach(walk); - } - } - - walk(mirror.superclass); - mirror.superinterfaces.forEach(walk); - - var result = _cache[mirror.reflectedType]; - - if (result == null) { - result = objectType( - MirrorSystem.getName(mirror.simpleName), - fields: fields, - isInterface: mirror.isAbstract, - interfaces: inheritsFrom, - description: _getDescription(mirror.metadata), - ); - _cache[mirror.reflectedType] = result; - walkMap(forward); - } - - return result as GraphQLObjectType; -} - -@deprecated -GraphQLEnumType enumTypeFromClassMirror(ClassMirror mirror) { - var values = []; - - for (var name in mirror.staticMembers.keys) { - if (name != #values) { - var methodMirror = mirror.staticMembers[name]; - values.add( - GraphQLEnumValue( - MirrorSystem.getName(name), - mirror.getField(name).reflectee, - description: _getDescription(methodMirror.metadata), - deprecationReason: _getDeprecationReason(methodMirror.metadata), - ), - ); - } - } - - return GraphQLEnumType( - MirrorSystem.getName(mirror.simpleName), - values, - description: _getDescription(mirror.metadata), - ); -} - -@deprecated -GraphQLObjectField fieldFromGetter( - Symbol name, MethodMirror mirror, Exclude exclude, ClassMirror clazz) { - var type = _getProvidedType(mirror.metadata); - var wasProvided = type != null; - - if (!wasProvided) { - var returnType = mirror.returnType; - - if (!clazz.isAssignableTo(returnType)) { - type = convertDartType(returnType.reflectedType, - mirror.returnType.typeArguments.map((t) => t.reflectedType).toList()); - } - } - - var nameString = _getSerializedName(name, mirror, clazz); - var defaultValue = _getDefaultValue(mirror); - - if (!wasProvided && (nameString == 'id' && _autoNames(clazz))) { - type = graphQLId; - } - - return field( - nameString, - type, - deprecationReason: _getDeprecationReason(mirror.metadata), - resolve: (obj, _) { - if (obj is Map && exclude?.canSerialize != true) { - return obj[nameString]; - } else if (obj != null && exclude?.canSerialize != true) { - return reflect(obj).getField(name); - } else { - return defaultValue; - } - }, - ); -} - -Exclude _getExclude(Symbol name, MethodMirror mirror) { - for (var obj in mirror.metadata) { - if (obj.reflectee is Exclude) { - var exclude = obj.reflectee as Exclude; - return exclude; - } - } - - return null; -} - -String _getSerializedName(Symbol name, MethodMirror mirror, ClassMirror clazz) { - // First search for an @Alias() - for (var obj in mirror.metadata) { - if (obj.reflectee is SerializableField) { - var alias = obj.reflectee as SerializableField; - return alias.alias; - } - } - - // Next, search for a @Serializable() - for (var obj in clazz.metadata) { - if (obj.reflectee is Serializable) { - var ann = obj.reflectee as Serializable; - - if (ann.autoSnakeCaseNames != false) { - return ReCase(MirrorSystem.getName(name)).snakeCase; - } - } - } - - return MirrorSystem.getName(name); -} - -dynamic _getDefaultValue(MethodMirror mirror) { - // Search for a @DefaultValue - for (var obj in mirror.metadata) { - if (obj.reflectee is SerializableField) { - var ann = obj.reflectee as SerializableField; - return ann.defaultValue; - } - } - - return null; -} - -bool _autoNames(ClassMirror clazz) { - // Search for a @Serializable() - for (var obj in clazz.metadata) { - if (obj.reflectee is Serializable) { - return true; - // var ann = obj.reflectee as Serializable; - // return ann.autoIdAndDateFields != false; - } - } - - return false; -} - -String _getDeprecationReason(List metadata) { - for (var obj in metadata) { - if (obj.reflectee is Deprecated) { - var expires = (obj.reflectee as Deprecated).message; - - if (expires == deprecated.message) { - return 'Expires after $expires'; - } else { - return deprecated.message; - } - } else if (obj.reflectee is GraphQLDocumentation) { - return (obj.reflectee as GraphQLDocumentation).deprecationReason; - } - } - - return null; -} - -String _getDescription(List metadata) { - for (var obj in metadata) { - if (obj.reflectee is GraphQLDocumentation) { - return (obj.reflectee as GraphQLDocumentation).description; - } - } - - return null; -} - -GraphQLType _getProvidedType(List metadata) { - for (var obj in metadata) { - if (obj.reflectee is GraphQLDocumentation) { - return (obj.reflectee as GraphQLDocumentation).type(); - } - } - - return null; -} diff --git a/packages/graphql/graphql_server/lib/src/apollo/remote_client.dart b/packages/graphql/graphql_server/lib/src/apollo/remote_client.dart deleted file mode 100644 index d8e4053f..00000000 --- a/packages/graphql/graphql_server/lib/src/apollo/remote_client.dart +++ /dev/null @@ -1,32 +0,0 @@ -import 'dart:async'; -import 'package:stream_channel/stream_channel.dart'; -import 'transport.dart'; - -class RemoteClient extends StreamChannelMixin { - final StreamChannel channel; - final StreamChannelController _ctrl = - StreamChannelController(); - - RemoteClient.withoutJson(this.channel) { - _ctrl.local.stream - .map((m) => m.toJson()) - .cast() - .forEach(channel.sink.add); - channel.stream.listen((m) { - _ctrl.local.sink.add(OperationMessage.fromJson(m)); - }); - } - - RemoteClient(StreamChannel channel) - : this.withoutJson(jsonDocument.bind(channel).cast()); - @override - StreamSink get sink => _ctrl.foreign.sink; - - @override - Stream get stream => _ctrl.foreign.stream; - - void close() { - channel.sink.close(); - _ctrl.local.sink.close(); - } -} diff --git a/packages/graphql/graphql_server/lib/src/apollo/server.dart b/packages/graphql/graphql_server/lib/src/apollo/server.dart deleted file mode 100644 index 6a16f917..00000000 --- a/packages/graphql/graphql_server/lib/src/apollo/server.dart +++ /dev/null @@ -1,133 +0,0 @@ -import 'dart:async'; -import 'remote_client.dart'; -import 'transport.dart'; - -abstract class Server { - final RemoteClient client; - final Duration keepAliveInterval; - final Completer _done = Completer(); - StreamSubscription _sub; - bool _init = false; - Timer _timer; - - Future get done => _done.future; - - Server(this.client, {this.keepAliveInterval}) { - _sub = client.stream.listen( - (msg) async { - if ((msg.type == OperationMessage.gqlConnectionInit) && !_init) { - try { - Map connectionParams; - if (msg.payload is Map) { - connectionParams = msg.payload as Map; - } else if (msg.payload != null) { - throw FormatException( - '${msg.type} payload must be a map (object).'); - } - - var connect = await onConnect(client, connectionParams); - if (!connect) throw false; - _init = true; - client.sink - .add(OperationMessage(OperationMessage.gqlConnectionAck)); - - if (keepAliveInterval != null) { - client.sink.add( - OperationMessage(OperationMessage.gqlConnectionKeepAlive)); - _timer ??= Timer.periodic(keepAliveInterval, (timer) { - client.sink.add(OperationMessage( - OperationMessage.gqlConnectionKeepAlive)); - }); - } - } catch (e) { - if (e == false) { - _reportError('The connection was rejected.'); - } else { - _reportError(e.toString()); - } - } - } else if (_init) { - if (msg.type == OperationMessage.gqlStart) { - if (msg.id == null) { - throw FormatException('${msg.type} id is required.'); - } - if (msg.payload == null) { - throw FormatException('${msg.type} payload is required.'); - } else if (msg.payload is! Map) { - throw FormatException( - '${msg.type} payload must be a map (object).'); - } - var payload = msg.payload as Map; - var query = payload['query']; - var variables = payload['variables']; - var operationName = payload['operationName']; - if (query == null || query is! String) { - throw FormatException( - '${msg.type} payload must contain a string named "query".'); - } - if (variables != null && variables is! Map) { - throw FormatException( - '${msg.type} payload\'s "variables" field must be a map (object).'); - } - if (operationName != null && operationName is! String) { - throw FormatException( - '${msg.type} payload\'s "operationName" field must be a string.'); - } - var result = await onOperation( - msg.id, - query as String, - (variables as Map)?.cast(), - operationName as String); - var data = result.data; - - if (result.errors.isNotEmpty) { - client.sink.add(OperationMessage(OperationMessage.gqlData, - id: msg.id, payload: {'errors': result.errors.toList()})); - } else { - if (data is Map && - data.keys.length == 1 && - data.containsKey('data')) { - data = data['data']; - } - - if (data is Stream) { - await for (var event in data) { - if (event is Map && - event.keys.length == 1 && - event.containsKey('data')) { - event = event['data']; - } - client.sink.add(OperationMessage(OperationMessage.gqlData, - id: msg.id, payload: {'data': event})); - } - } else { - client.sink.add(OperationMessage(OperationMessage.gqlData, - id: msg.id, payload: {'data': data})); - } - } - - // c.complete(); - client.sink.add( - OperationMessage(OperationMessage.gqlComplete, id: msg.id)); - } else if (msg.type == OperationMessage.gqlConnectionTerminate) { - await _sub?.cancel(); - } - } - }, - onError: _done.completeError, - onDone: () { - _done.complete(); - _timer?.cancel(); - }); - } - - void _reportError(String message) { - client.sink.add(OperationMessage(OperationMessage.gqlConnectionError, - payload: {'message': message})); - } - - FutureOr onConnect(RemoteClient client, [Map connectionParams]); - - FutureOr onOperation(String id, String query, - [Map variables, String operationName]); -} diff --git a/packages/graphql/graphql_server/lib/src/apollo/transport.dart b/packages/graphql/graphql_server/lib/src/apollo/transport.dart deleted file mode 100644 index dac18d65..00000000 --- a/packages/graphql/graphql_server/lib/src/apollo/transport.dart +++ /dev/null @@ -1,78 +0,0 @@ -import 'package:graphql_schema/graphql_schema.dart'; - -/// A basic message in the Apollo WebSocket protocol. -class OperationMessage { - static const String gqlConnectionInit = 'connection_init', - gqlConnectionAck = 'connection_ack', - gqlConnectionKeepAlive = 'ka', - gqlConnectionError = 'connection_error', - gqlStart = 'start', - gqlStop = 'stop', - gqlConnectionTerminate = 'connection_terminate', - gqlData = 'data', - gqlError = 'error', - gqlComplete = 'complete'; - static const String legacyGqlConnectionInit = 'connection_init', - legacyGqlConnectionAck = 'connection_ack', - legacyGqlConnectionKeepAlive = 'ka', - legacyGqlConnectionError = 'connection_error', - legacyGqlStart = 'start', - legacyGqlStop = 'stop', - legacyGqlConnectionTerminate = 'connection_terminate', - legacyGqlData = 'data', - legacyGqlError = 'error', - legacyGqlComplete = 'complete'; - - // static const String gqlConnectionInit = 'GQL_CONNECTION_INIT', - // gqlConnectionAck = 'GQL_CONNECTION_ACK', - // gqlConnectionKeepAlive = 'GQL_CONNECTION_KEEP_ALIVE', - // gqlConnectionError = 'GQL_CONNECTION_ERROR', - // gqlStart = 'GQL_START', - // gqlStop = 'GQL_STOP', - // gqlConnectionTerminate = 'GQL_CONNECTION_TERMINATE', - // gqlData = 'GQL_DATA', - // gqlError = 'GQL_ERROR', - // gqlComplete = 'GQL_COMPLETE'; - final dynamic payload; - final String id; - final String type; - - OperationMessage(this.type, {this.payload, this.id}); - - factory OperationMessage.fromJson(Map map) { - var type = map['type']; - var payload = map['payload']; - var id = map['id']; - - if (type == null) { - throw ArgumentError.notNull('type'); - } else if (type is! String) { - throw ArgumentError.value(type, 'type', 'must be a string'); - } else if (id is num) { - id = id.toString(); - } else if (id != null && id is! String) { - throw ArgumentError.value(id, 'id', 'must be a string or number'); - } - - // TODO: This is technically a violation of the spec. - // https://github.com/apollographql/subscriptions-transport-ws/issues/551 - if (map.containsKey('query') || - map.containsKey('operationName') || - map.containsKey('variables')) payload = Map.from(map); - return OperationMessage(type as String, id: id as String, payload: payload); - } - - Map toJson() { - var out = {'type': type}; - if (id != null) out['id'] = id; - if (payload != null) out['payload'] = payload; - return out; - } -} - -class GraphQLResult { - final dynamic data; - final Iterable errors; - - GraphQLResult(this.data, {this.errors = const []}); -} diff --git a/packages/graphql/graphql_server/lib/subscriptions_transport_ws.dart b/packages/graphql/graphql_server/lib/subscriptions_transport_ws.dart deleted file mode 100644 index 2c9735e9..00000000 --- a/packages/graphql/graphql_server/lib/subscriptions_transport_ws.dart +++ /dev/null @@ -1,9 +0,0 @@ -/// An implementation of Apollo's `subscriptions-transport-ws` in Dart. -/// -/// See: -/// https://github.com/apollographql/subscriptions-transport-ws/blob/master/PROTOCOL.md -library graphql_server.subscriptions_transport_ws; - -export 'src/apollo/remote_client.dart'; -export 'src/apollo/server.dart'; -export 'src/apollo/transport.dart'; diff --git a/packages/graphql/graphql_server/mono_pkg.yaml b/packages/graphql/graphql_server/mono_pkg.yaml deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/graphql/graphql_server/pubspec.yaml b/packages/graphql/graphql_server/pubspec.yaml deleted file mode 100644 index 93a8750a..00000000 --- a/packages/graphql/graphql_server/pubspec.yaml +++ /dev/null @@ -1,25 +0,0 @@ -name: graphql_server -version: 1.1.0 -author: Tobe O -description: Base package for implementing GraphQL servers. You might prefer `package:angel_graphql`, the fastest way to implement GraphQL backends in Dart. -homepage: https://github.com/angel-dart/graphql -environment: - sdk: ">=2.10.0 <2.12.0" -dependencies: - angel_serialize: #^2.0.0 - path: ../../serialize/angel_serialize - collection: ^1.0.0 - graphql_schema: #^1.0.0 - path: ../graphql_schema - graphql_parser: #^1.0.0 - path: ../graphql_parser - meta: ^1.0.0 - recase: ^2.0.0 - stream_channel: ^2.0.0 - tuple: ^1.0.0 -dev_dependencies: - pedantic: ^1.0.0 - test: ^1.15.7 -#dependency_overrides: -# graphql_parser: -# path: ../graphql_parser diff --git a/packages/graphql/graphql_server/test/common.dart b/packages/graphql/graphql_server/test/common.dart deleted file mode 100644 index 9be47053..00000000 --- a/packages/graphql/graphql_server/test/common.dart +++ /dev/null @@ -1,5 +0,0 @@ -import 'package:graphql_schema/graphql_schema.dart'; -import 'package:test/test.dart'; - -final Matcher throwsAGraphQLException = - throwsA(predicate((x) => x is GraphQLException, 'is a GraphQL exception')); diff --git a/packages/graphql/graphql_server/test/mirrors_test.dart b/packages/graphql/graphql_server/test/mirrors_test.dart deleted file mode 100644 index 259b825d..00000000 --- a/packages/graphql/graphql_server/test/mirrors_test.dart +++ /dev/null @@ -1,52 +0,0 @@ -import 'package:graphql_schema/graphql_schema.dart'; -import 'package:graphql_server/mirrors.dart'; -import 'package:test/test.dart'; - -void main() { - group('convertDartType', () { - group('on enum', () { - // ignore: deprecated_member_use_from_same_package - var type = convertDartType(RomanceLanguage); - var asEnumType = type as GraphQLEnumType; - - test('produces enum type', () { - expect(type is GraphQLEnumType, true); - }); - - test('rejects invalid value', () { - expect(asEnumType.validate('@root', 'GERMAN').successful, false); - }); - - test('accepts valid value', () { - expect(asEnumType.validate('@root', 'SPANISH').successful, true); - }); - - test('deserializes to concrete value', () { - expect(asEnumType.deserialize('ITALIAN'), RomanceLanguage.ITALIAN); - }); - - test('serializes to concrete value', () { - expect(asEnumType.serialize(RomanceLanguage.FRANCE), 'FRANCE'); - }); - - test('can serialize null', () { - expect(asEnumType.serialize(null), null); - }); - - test('fails to serialize invalid value', () { - expect(() => asEnumType.serialize(34), throwsStateError); - }); - - test('fails to deserialize invalid value', () { - expect(() => asEnumType.deserialize('JAPANESE'), throwsStateError); - }); - }); - }); -} - -@graphQLClass -enum RomanceLanguage { - SPANISH, - FRANCE, - ITALIAN, -} diff --git a/packages/graphql/graphql_server/test/query_test.dart b/packages/graphql/graphql_server/test/query_test.dart deleted file mode 100644 index 335fe284..00000000 --- a/packages/graphql/graphql_server/test/query_test.dart +++ /dev/null @@ -1,52 +0,0 @@ -import 'package:graphql_schema/graphql_schema.dart'; -import 'package:graphql_server/graphql_server.dart'; -import 'package:test/test.dart'; - -void main() { - test('single element', () async { - var todoType = objectType('todo', fields: [ - field( - 'text', - graphQLString, - resolve: (obj, args) => obj.text, - ), - field( - 'completed', - graphQLBoolean, - resolve: (obj, args) => obj.completed, - ), - ]); - - var schema = graphQLSchema( - queryType: objectType('api', fields: [ - field( - 'todos', - listOf(todoType), - resolve: (_, __) => [ - Todo( - text: 'Clean your room!', - completed: false, - ) - ], - ), - ]), - ); - - var graphql = GraphQL(schema); - var result = await graphql.parseAndExecute('{ todos { text } }'); - - print(result); - expect(result, { - 'todos': [ - {'text': 'Clean your room!'} - ] - }); - }); -} - -class Todo { - final String text; - final bool completed; - - Todo({this.text, this.completed}); -} diff --git a/packages/graphql/graphql_server/test/subscription_test.dart b/packages/graphql/graphql_server/test/subscription_test.dart deleted file mode 100644 index 5885e03b..00000000 --- a/packages/graphql/graphql_server/test/subscription_test.dart +++ /dev/null @@ -1,51 +0,0 @@ -import 'dart:async'; -import 'package:graphql_schema/graphql_schema.dart'; -import 'package:graphql_server/graphql_server.dart'; -import 'package:test/test.dart'; - -void main() { - var episodes = [ - {'name': 'The Phantom Menace'}, - {'name': 'Attack of the Clones'}, - {'name': 'Attack of the Clones'} - ]; - var episodesAsData = episodes.map((ep) { - return { - 'data': {'prequels': ep} - }; - }); - - Stream> resolveEpisodes(_, __) => - Stream.fromIterable(episodes) - .map((ep) => {'prequels': ep, 'not_selected': 1337}); - - var episodeType = objectType('Episode', fields: [ - field('name', graphQLString.nonNullable()), - field('not_selected', graphQLInt), - ]); - - var schema = graphQLSchema( - queryType: objectType('TestQuery', fields: [ - field('episodes', graphQLInt, resolve: (_, __) => episodes), - ]), - subscriptionType: objectType('TestSubscription', fields: [ - field('prequels', episodeType, resolve: resolveEpisodes), - ]), - ); - - var graphQL = GraphQL(schema); - - test('subscribe with selection', () async { - var stream = await graphQL.parseAndExecute(''' - subscription { - prequels { - name - } - } - ''') as Stream>; - - var asList = await stream.toList(); - print(asList); - expect(asList, episodesAsData); - }); -} diff --git a/packages/graphql/img/angel_graphql.png b/packages/graphql/img/angel_graphql.png deleted file mode 100644 index b00840a6ef60fa3dc3fca523faf5d89c40feae8e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 129666 zcmdpcV{~Rs({3~qPHfxB9ox3;Ol(^-v2EM7GqG*kwv&_R{dm?{Yu^87|Ju8|&{fq} zb#?a+k&_Yq0fh+#1O)U$Tuev-2}$0ARu%$GeJQ)aX~?RIeQyp zGfN{NAhm!5b#NtQ$-0Y_@jtN+6Y}=ohuIIwDJ3ViV&&n1WAcN+&27tK9@ZIJ0Q{$+;y_XyKS2@Dj zHp&G?_|_^=b^=%L5CV|i0emZ;qY%1pO>p9`m~ir7y>6PbHb3RY>OokR&4ZezdBJK< zAXiGnkTYnY`$U~~`OMB>>=Wwz2%f%CUNHTRUwYEAys>CNX9f_Hm0MeKU=DHwYID1I z_MV@Dg@br0#Icun?FOUH-KVcXLEmD2er8=fbxGRF?OoD?MN909vNW#Ox{ccW&N0?R zpT==V+|f4+&~pcSeD$!pwb`cV5;F+WeH+c(b`PEeVg#Z~Koj4D=}w0@fP<`M`V?Ng zyJltLr`z#Z+TiW!^DY9M3BxwLli)>O!?IStMu_j7*EG5^5Q5@3dJl6Q9$MXK8hfQ@ zb<9R)+RDav<&pT7AiR-sO--DkO$M>?a*u9u?TM|@WW=zG0^`-@oWsIN(6PNWX_GVa z`XG(!E^+ltZnzc!%(KYMG+9-^z+Hnl(>@nwM>RL~25FUIU4nZ7@A5@GgpO7|*GWO& z)IWDbnO(s#tfrq4)=+Sb9@{QG!4NGuA9DHC{2SgQtxX4jVoUBLVNLDyVDEnMY<-In zy9dg_2YPZDU(XQqKCedyLBt2u-TFc7Bk%oayJ8K=pXrPb>nRY;3h_BB>(VxlB}8x+ z!8?~xM0~Yu9kFtO08t2!4Kv0Ef5U0traF{0jol3Qv8uGbd7tt?{kmMYF2wnO-qjXUt;^$Qb6j3E(qKI0UZ; z0?nU>|6=o_xW5GDQ*8NWj@PRuFKH0Z=J?(0xe3Sp^C}DNhUJx&jPi#Q^n9dyuzRRE z-}<-qVp1iXQlxu5=+BUdkn^P{?$q-}p5MXPpP!gfcNSwbRRN<)!($`mpXQ(l8}ta8 zVZs0=>cq3lQ?%|fzq5snc2a^&g*MlHL&F$tM~lnNWsS~N>&s(!hsRAO#M;4LK^A2o>lJsA*gR*`qYCiva`+}tM0$b~D8TrkYQ*62zc{A8 zfB%E52JEo~@<8DIAh;6`liN*T3zqLIWsA7ySGUDQ4vMmc*$jE%`~3=@>-!`h96C@{ zj9Lm9UN@H-m<2r8Ha=k=Pz^shUdn1%%kQhb9{RdZK-l0#f5^53 znvpx97JJ~fO|F2rzWey2$pHz6{1my)A(p2k=Z;4iLD}~s%tMsJCu% zz|+rM`jTXjF_JMHDXdy&Qu;78>O>4GUuBVnOlTG$5BRhIn(hU?w3?13yE72jAcJ1< zEhbwPHbh#Gq)<-3wor?n`)yLYQCA5rI2~AN3+~dNOJd!D>*^}v5QzX+c)5~etY1%3J zso@#*>2I?})7m*660Cwzd1!^K*^jxhIe^d^j(hPZ}0M%zE9^{&+YA8;|Q%=;P>V8|@k~>OmWh>bH%u^h6q?nKbD~8S@Tq4Dbwg59Lg3565)d z#Tg_c9Uvdp?{f{Q4=fM2{OKPz>O&cD3M@;oh)he-Oym5;8Pyi!kr?z_G;T19EUGBv z5EOt^1#1IuLvTs7;l?AwW6&wq8Rn_&Y4Jw*2Ky%d#{5PEf($|l!UN(4LIZN^%jJve z8w6Gc78C#>Kq=rYP!zBdkmxV$pWz<`xrvgAppQb25Q0>K=td-gJdenYuR*y22t-jt zfJUZ5I7JBRN9lj>3+rnm(Ssy`^a()>+0ahbE^QNVPPo8~&5xan36Cw0^(5=3Hlj@+ zc2Yg5tIw`4bBuIsyOYHbPQg#HPg$(Jt1YY*uf4C`-0R!t+7I1(*$=r1yb0Pr-Rq(h zBX^}rS9C2I$~Mh$m8uc86BJhuDOajsDx)qwtJEsz%I_)uSrJ=sBZQJyTIR0S!0#k1 zElwkFUbuqhB!16#Pj$lBChY8SNxR8i*BjFM6($>&uUvYsqsg}_ z`5OCBADJxkYeG3=vX!CLaGkSN(%szs+I{?m+>7WP=A9PQ9TeQJ?t5O~TVQ9Pa^S5< zs0esOY6Sg&@c{dPAgLBwx0_3w|NXA#S< zj(D$~*X+_o?t9&R(fufJBnTpi z8(<$a;QtUP?q3iXfg{Hm?W31zDbk4y8*urfDojs^b~z&^H%63bQ`k%dMVLmEQ)DwV zCk!&=I2+hgF;I~-kT_#Af3RO*z{R&qqAeoZHLK~!oTUK4+s#Kz-?iO$>;f$h% zqR#9we{Md>{BGeiA3Kj`k!-PM&FAMqaF+!d~EdoO;}L9sNjL zteB{HkFvydYDj6|cC&nHZqP33I1U+z3oJ61y>u#eT=OctD{oY+xt(z6KXhr0Z#8dA zXghUR@;LEud1QGoyXW@I`P{MV6923N9{s(+AJm;BXf0>}=+K#HhjPDnVl#I=ciO=k zOAAL>iSd=6n4W3+X=5=EKY-gl>$CX0aq)g?H+da}w2gEcN1@nP;%k<9Jc7}Z5~$w0 zoC)W_BjpYA+RT#l5^|w5+k`9+aQ6_4I{HoCD{8J`zG8+_!p z)WsA}0%G>Xy2=qx^A#nAana5<$vHPLatZ>?9sV zLfG7?sV?PQ=PK?FA|?lV3#+@cWIRSboGsCHuI23f6d;FqCfz#r3B(A1t9VaTQ!I{T%V@i2edkJZy zY*F;g<2tu^(}d3so{^17>6+mr;epP%87BnL&pJ!Qo_CVBYZDb!66NLT^3ie5X5Mbx zqyN*0!Nz=1X}13Su5WBw{dhS94h2u}VDAu>XWsMSP2h2VqW%7DZc%Vkt&{sB^PR}> zcm0uH-*lh(YT(?#!NVIg-{LkPh<{TPeFxrw4}`m-)@SedFduC*8Xb&&Shz)F{|VmMYGT zejaeIj5ou#lD9(;caT#*O206HTEV!UA@H@Km2IwV3k1-Z#ax9v?w>F}jdsA`>~VgE znMh=FhjX_lKYfUa&P43J#UJH)C`v~i7o`-%F+>`EB-}qe9feFTLz5-hqsn+qW=y`u z^QvAw-`!xW)RhVo^e0KQPDEs7b~D$4s}7ee8;krs#&4JMnojD+vx4o%+9DU0PT4Esnr70{BD_)siu-N zqJq+OVy~f_5r}ij6B&8XL1BJ1eVkD|n_pt?8`TOdU6y|MaaY4LOdLPpyrBm`t0eSQ`BtH-GOg zoMu^^nABPSeMEQSI({5oR{|Y3s<{}-oip^@Rr}c8+4t^#;rghfP$QasXbqsO(!U(# z0ryn)TzpS`LjtV_<=1nViqY$UcNEh+nx@OB-Un4SMB5vy46hD-LQqF<;529Apbw-v z;4k;Uc38XWE)^WUo`B4S3=7gka)^2&Jthk)s>Usl`c}dl8BxS7TQxj1LTp5VJ&1$H zW5><8Yp54FP4S`_IG>+Te7E$q!C-#TTt`c{i^6^M{-K1k!v*71>jGsFj#&>km>HAVjS0`&wX&e* z{ycAd(DU3~)-%i4Y0Z^osb!jEp`+-~@$v|| zY}6)o&r=OfLawNccu-a91qj8~!0}tjPxWuK*Ar3qqiWQXn3cA9{J_K;LlR z9lZI(c0xq$WsLuT_Wc5hHA@9mCANtKJ{A*kLt*meq5HN#;4TI;BXZMgd&CwC*T}z1 z2X@=tT8-ujGko*1r5q150)i4$%J(DZ+LYOmt`+7TN-&CEkfBzE+JAn4^rxmRdOF1g z@dZgH9G-ud=pTf12o!&1DCp2IWXbr%coZd5O1M&$TzLA7r<9eykTP@r*#I;ebD7V|^ z_9qmuYLKdLHjqZp;33H&62S=l2mRp07ndAlDfs)O6_mZ?jDT0Ii%`#2->lq{*m#Dx zo5B&YdHDvO`^a@G%qXVShSvHZCu2vn``^H*%ZFD3u1LNV2^e|oSpmKU1F)o1K`t1HbPQ_x&U^@uwdD=vSc z*Wh#D)sbj09EhwRyEC7rdecMv#N8+kMA4%53ob`YM{jt#dw(PUy875gcdi@d&#F>+1SdiC?xQngiZLChRHX)bHPSOmfvm7wbx4Zsv}` zq27KLx)%NxEfBOLSP(RVLs_NVRib#AI9)w`w-`D_dir$Caf)$VhDnZIijIMC$tq6Q zVY*<=V>7I8q=yrnZsz7(bbgC-gAHI~X7_PYUW+?=@WgxkfOxcq1D3_B^1S5a(e6a@ zwg4XceZ&9IEl*$~nAXb^t={v4D3=f*`eSfvK%>tH&l3ZX4)5do7Hq>{B_V1qgvs)* zM#@2T4kqesA)`>~(79oD&v+tyLQ;CzPn#==mn5pa)BKh_lNWk?BIdMue~||5Vt9$$ z`dI$EP`)c=&Hi}Wvh89vEu&VupPR^w_oWL~rVAS{)9rSb<}UJQx}AdUiff~u%(LXc zqogE1m9_=NX$2OqcctYdZ+N*k$Dbd>ze%fsdGK+Of1PF{dH#Zk1~UYX$q^{VcmZPU zeX#}egv1q@&XJO%C^nw^u7QISR4H0z;7Es&Oi+&g0O1T)6hhU%d!6&-?Ms>C4^jw` zjh;PM)Gk{faUX3eot`U`yPaoN=#;0O&nXTN|4b+Fj~PO9OAC z4PqlBI>cOraKV|R*wEu~@WudE;V<6`ol@Nf5N-;y_LY!;xtK||N|Hz<4b2UAM!#16 zsWi=v&tEH*C^#te)&>n)Q^s<7a&ov&`B567C4D62F+QmgsKL23viyUynZua_tF3)$ zcek+}u#7_(;0EJL;eqyw_!bE!2bTCv)8DtcZEp(VVrb!LNUh2*3uy$&APR=GqUew4 zbxHl;-fYk8Dk5YkWFT1L>H27n@*Arz_aU+Um;H6)>87CsBG});Z?RbOWaY$G2_(k!oYKy zHJaP-#opoR1gk72r76Y$>oSg1E>3**O6msuZm`!Oix7~u84$#(Jt=?>YK)RoOKAe{}oz=e` zS$GS29U8U5!-G$t1xlVCAHVDY+L8gTj;U*DQE6>ykq;!svH>!MU3uO#c`eWRmi=^& zdIFCp_V)M*_yi^9oYI&f?|uLR0?ss3Qgc+3mf|q5v7*&CwE1a7>uP2Db;ke%#O2EI z^=f70sE_YzWohle;mS?;FA9#Y_kWrJg!um=akStjRFjs&7qqcA!e^#sqNO9`fx^ef z=dw36=1>q4`A_z*FK$9pM@L%@0Kmn?h1P|U*2dlhK+n$34xnQIFfh=3QP4QJSv%^x z(pWnX{fChMk|Si~U|?@%>u6?UjsK5a{hu~Yj@*QV|0w$J=Rd}2=xONy|1JBAmFu5Y4mmSdBTF?QGboPDf4crh<^N(;{~uO% zI=27K`M-MplamYZj|KnBqW^H$zgoZi#RJ6!_;26yK)IErVgLd00f`IoE4c!nWq|9U z^e+s49w+dD{GQ_cy2XKl5L3=1WIMIIEXe4bcN6K6?V@9>~HhglmNOJS_5>uPgxev|_3g9IkP2lM|04-X>1 z2LbW_+sALk2)>~bX92Q5&k(anTawX~e>E{1p%@*CMfJAT=WYuhh2YNbrK~ z!;c;uSP`;^4y-N6Ld1V}rLELfJyUZQt;qiDJ{OMec`o_i>8}`nD{c&Vmtv;M&fnhL z-qZB|n{a`MY{fHHXGsJeDjsWrIDeDu{(Dq^@A7TM(^Y1ji5$h{e2@v^MD<>Z!czQg zRD3`X=`ew(aXFENy5qy2W305(~}JbU~T)L@2r zG=!nrdHOyykiRm!3gSlxp76!v1T%DOs}N0wn1em2cF5G*oBv4){yS8*zzDYhL=Pb< zk(=5V|v-i(6$riw%fy`ukl-_H&?BpnlK}ntG znJkumak14kZZnO`eXH|eF^NR~@3`fogLpE}ejx2)b-SbX9Ipb5o?eCM!9O&>X6`)- zCFQu6Uf!eW54pBSS`-Hg1^g`mutkDJCLt`(?z-n*hE!s>>)xg%9IH9E|7hyO-Zazk zImOuKpxI28-TA9eA%5#2T`l0BGi7z%k3F$*2de9284k{(pPkoa?A<28_BtsflIi+( zjo$7p6CMJ2+2HV2G~_SvUzlOmT{5ArSRJb8vAlk67Lb~%Q3Wd;`=xh-9cj-5#U z&D3IxfpGm9?Ob$f!Qo)18i>JZbCaB~tA=WsSKTz|kTglVzRL7%nzn0Z`Ze?9^j1Rc z?-_DS79`n>UuQ5+ddjv@i+}MRI#f$K#99w@Yo{2yaV35m9XcJiJG*gBH7>9rF^T?1 zF!wXV8qR23t&r;9M*CYa?iX*wz{NzOh|S&k2;+%63S1z;;;cdQ zY?B0Q9A^SO7o#?33vRQrPDff zKUDBUpj$W-m0J~CQZf}WRHvj=GkmpE|1(-EfuL5&_xYZj+I38140(~ERJw43CE>Tp z$0wr-`bF*%x}JZB(61`6bjPfi=H; z{A1;%ntq(xnxrnyA$1xf%0lXqyb@*-*T_EatX_(Wo3TZ{FiJC^A?Dans_OCmag#Sb zJ>4@X&0VtguM_ht6t4XEL`1t0z@Xo`L`ClN;xj}msPZ_H3R%rH10vk9O^Oy>#I<}X z_S|t`Ip-M<7$fSYm$PJS)*7i6B__!an{^7KPJ2D63yStUt*4n7yzTQ2M zJ&5WbiB>gA?o3`wEM;f)o_t1a%K9jar|7e66EerGKj*(R&SO?aD{>p~%r^7>IFX?; zE-;B-?Y}p}R`zz=v7sIn&(z@fpeyFA2u{hAH%3!6 z8##=V*YB`Ft#sNU{I?Zs7n0sv zX+9@!_i(RYnV2AzRk*0%@^9k$Ri01-8zm|8;6?PF-F5Pm&xAA3#L;Gjraee$%|Z;QkbSab zgx1vL;vs?3%(_}OMr~|#^^`zvMQLH|@Wof!(Lk=gc%nb7h*v`$37r|~;%mk5_poA-Q^};1Sa#1 z1-DFp4=gTMu+eB@j%t;T^*K|~&NE(+14G^TNyI_AHQJ)8`f;rk9!r?!u-XMH+JS+% zC!+HN^*Z_N;CPRO@u5TNi>+7v5AorsEIR!jSJdF!j6V|@oDCvHcDnLZ}}crtHR&Yh>F++>0hxaw?HYjv>>p<`n&ob zYXtKf(BbhKInIMQ)cR($IUkfTHnMn%*=uY^g)#cRzEQ#yxKvCQp^#Tx_o#~7AnGmgM(8c z5$lNmlp`V{R@-dyNaAdphYYarFRkocQ^+s9_)oIbRX6nSD&|(-LuOeS>sy2k776K} zBJqrl^~@tiOhWc7nD{4tgV2;@;vs|3%tFvW#kZuHeoEhpx4JzTM?gW@zrB_z0!db_ zGak46nl4CDKv`v9a36k}!ZtP`Q8aVkL_cV@FXcip*_0}jbtyF%%cF@R8wa{blkWa?fLP%64Xn*%M_*U%|YlgDKh3xX|VjSHqZjM zlbJBMpUwwbYY&H@Y(As&|3T{0dUIocwp<5ZI~R7S)MApdOfQ&+R4GE3*&k40(#|!F z+L$?YBc;0JJ}`=8rGE-ZGwJw09rl$}S{ZdWN{UPF5@Ri$)lL&5iqiV06!eELJqzqq zvdrr>>uoN83ASAr*)S9@!asR)DOo8QB0$dxzc#+smO6I~yfJdtk+B_WMVWoo>+I)^ z%AAYJ9^+&86!j&E!o9CtFJXLlZ&Ca?u9%8Ye{GzRq$}cw!b`+K2oqDGfnRF}m3w=O z&}B?RxlkpjK3hoc(wyjeRMQZ=@yvj^KglofM%zb*hR+kjlhX$8Vu=wN72VBTNI{vK zQ6b&Q;zOjv!v^he#qB&#Bf#I=N-h@KTN#|ErqT@S5qZuxJ0xO?Jv}w6$U4t!y9ERV z1!Wiqt;q4vb9H5FXktP{Obq69GFOsAt@VW@HbP5okpnirYNzlK17ZDBdWJy^{|W;o zTq-Eds2KJMd`q0X8!`E2cmGi$BmGkZ+Nk(|3ejdR1=L2|?He)mrGIs}Sh9C$w>je` zP>j%m#Kgo5jf@D`+1b%>M$p~h0c!}p(@;uRo>6DQ`$s8lIi@p0J6uD5vk^0?c~zCU-a7p+izq_|g`Xz#^y*3T~H4 z7V=~f5#ew^#K>NU$=0#v&F zTuYGpCD-=Ls!f;v@l1hQlQmA{Rf9Nfjkj02$3+V|n=SqX`ysa1bdmHDR-@ndJBQJt z++2ZEFnwXK5-GL2?%XWPaJMqde=(u3JSrZ&KHPyT;av(WxD@P5MS)mt zLE3I%zxz;+jC}%AsyFkC#r2X)wRi7aeDne@e-z6-rrynOEbF_Y5j`6emUG{qZ=t)-e1>B5XLIs zID8Y=@nVZHpbF%b-g~CDNv_HuopTeF5*}B+_tMT2#LZmnP_V}C!eM;;1+Ql{_Y^29 z_QClB^mo#zadsT_eJ!i{PIM3=&xWXD_4s74yjn=1k0BtR)k zVI9A=Pl&BGLp>QDe%{M=Cb_k~?nY0#ks9)|Xajx5CfEJ`wWg_nHZ|oND7Uza<2yp* zy+hJa1RYkpD~+woMa>{CqcR4QX|(YjvozNae{&os<6%|`XPK58Js4- zpbCqwXkJ}!NaMFCa6BPXa@~ibsM|yu-Px~S3&xnmgLaLKjF`jQ(korN>N1}(`Q5fWArKOVoBrdv4d_jlC_M9W`??O%&YZPgq_ta*Rp<)!hXH_tiQ zj{(Ob%Vm*nH#8c;*Lkz8WL-6>ik$+R3bj^yML*w^n|4o{czRH9V&#-14hG^=sYsL(1kLz}+qE0>OR-;px~? zZ@^v@rGhFaZplQet%00wW*wARZqB*Z_eJT?%8~?0pXNxr8nw)Z5feX-s9YIw@e;x< z+N&|f$vHWFBF?B%<3Xa54m%^^XSPJu(4!+Z^DB^R2Y~2D4Yq$j2|lIPV}YxpdKlN3 z?bk+6`MVRD)^oR2k3Zzn1GrOmvz?{wrsRNAs)C{sm~-5Iy!b;r&1Ulwki1yl{S8zY zGwfRh*@9#-CjIzvyOOM3$tgH07ETEUNjfIs$W7fax=>zC9wIyzitF4y$v1M!C_brp zpEO6=p{h`MMs2)|FWZvxMU*GS{hjEIQHz=nUEn93?SZ`M?q^(?6RE-wT|Mm{L58 zNsbG}J=7DZ78oNmbiLici-H2rAqlEGb2#IM3BDd&fP*))>-~x4HX23Q_E0WUsi-d* zL1Dt|u*M?0!g&doh7=;^dif9H)V{$ML>5A zQT?5LM=R6q@+Y&t0m~#8J!5eleTT#0gtFh&n~x)=rwERaPjp96lwy_6x%}QlBu3y~ zqE)vbt7O>7bog5!&1#;yq^g_8f_KPi(B`*V;@r_{pRM^pkv!=RawUJ^?6atV&n1e?1}`ad%`&ftymt4@ zi>9OPS7J;b{xJkM18LShqg9;6lMV1Y{ijrC)f%YdOgV5uec@~z~ z8@!(IQJ2q1aS!?W3ptKVA;EoVRvcTk?&9R6+$KbyezUm#{_#7Hi@Jk&gCL8zbYwP5 z-}9xfZkY{~wZsP|UGH+T^mq`aDU)36^-pnF$y&blka_rsHYSZd>31)4w9VniCv49~ zImtCm!1h$8hEn`20=EuwQc)V4sD*kK`q;2Z&6oIVH{CSoECzXHLvKuDZuL~|Dve!- zPF~2oXLjqSJrXWI`%vDm;)D&-U%G`H3q0~ZX6sC3wOrO`mo&$sl772n*6w3o*8yEl zDrDNhiwD>&!314O2=A%lsfI{{-fdiwH$)&E zT9ss^ckz1^x!%>yt(f78jnqEsNuG3L8uW1uUDTAaTJET*1XyYzMZm}!iPEWAut9=GIm%C3YcyIO-|kCG1l&H zvhsqm*?F6k;nc(Ha>xJjkEyep6DRSUqL>){QM?U{?V<=P56=Z4!+#aV;o za7Rh)`2_xjEhu85L@H~NI*MmKulltKB`UP6z*1SAr0J#wKcTP(TNN*{M$wLQvw*^f zoAeJ+X$$L|>L9n3!C++nSDjsfvhSGxvcir;XT3rxmCBBnlran8_WJoJ9bCkq4_$A0 z4QqSS&RGA4X{}`P`{Z^6>jqzuOa`6apI?|_ov#<1XG=Apy8{tr1gs*-BvCL1yE&Yd zX)IPfkDESKDATz{lIP7d!(Hc%tHr$i^MY}*X?r(H0NN-g7S)56o0GBzT$$Z#?Q4aK z-!z3rtTM!CQjKpwi2RCL&zz@xr-eT->{9}Ner<@K4o(9M(}Ncmvc0Ygl9(&M3gmv6 zR26gtexj0l0C59Q;&##EtA0=UL-Nao0L+OTT2SNruOgdHye84ku$Cr`D8gdpcr1Rm z36`-GoIugcBk5hLU&(=o*|}+R?Zl318MWq5 zyQ22IK7*HXEdW>PbVtdJebFQ3<_!1vWG(M1dq^##q4ff~^;nNMx)K;``$-I?>yDN; zX)RP|DiCwj4OFkE(_~)C8YRX1GPS-^dEh_fzTN_h&!{lPdX0I z{3g=p#3jjCd}#H8yNus#T|5go9Lby@w6`*?|3QbmTKW<@kucc6DmpO6JD<$ zH>Dx{O3=^E>ls+E2X|-3r|>*|@A?)4)y{iKDYU|4qPi%v;%|;>El76dR959d(ZMLh zYL*j%IC&m%^Ya9qba0#KR0TiXI1*JZCtiF4l|s7T)$wgHu?j`wJr}<^p9l4bx0)y&6q*`%(}A{X{z4O=bq!N=II?+^8z?yj&O zw8TB6(_Kgwow0Vp(lv0h6xDQ4XFS-C4G&+xelJ<=@+zex6@rKag`i}Q@t}s_r-_=Ej#Q3@q zNCQr;tC*^OvUY7H`bj@p;_js`dwFMXknE)Xb)NFfUOp3H-_>_sDcOb1ry7h9Nh=Or z>i7_$kD}@pAIZ77drP%j!pJ^Xl!sGuQ%#@* zxkfG2TZ&M}YP$6D8cT^j&Pgu`*A344B!`IVegZL?327`=8r1xD&$^v8(~wYxyA>LH zb&4u;#nh*FJIhOcT*eO1jzQ(RIqRY-^++Jv>5)r!0Pb8sx;Kf6>^D))TfMEZy@8NY zAyPCY{$m1=nOllPx8qGLP?2S(0u1$3N;C?SG(%>v@?UPQLZUn=D{Tr3pu&)NS@e(?%c&FIwKx z3SPa9U5mZj|6mB->=`zocRP@>5}FKVubk#7;To-Ne(vBr?FXRLmVeulW$tKI)07A0pgo=`s~$wTjTsKc;#|dOvQRd#5@$K=KJN!rj>y6$XQ#RE|1v*2z=-2lp{Ti)&x@h2Uxm_~o_9I~L}^FtGz{wLT#xEqMYY$a_PgrNV?eGZW zsk?L?j8}T#i!cIpU<~1CRmiK zy51id!Hc|4d|2m|+!pPf@ECLD2Swh2(8t`Mu4pddxDhlM>P(!^SxXgZBx>^Bo|{y6dl~ z*7pb$aJC*ZhUb$!yJ|nhOiuQz+DQEobfB7*oW1@KG+eTp3pNhg{57e{p7q{y4uv&& zZ_(xRc0KrXQdXtc#1vVIcDwicyCvu>CocDdM~OO|z?8)+s`2ZTw?@xmR%JUEcp8t+ z*M%>q`G8}^*^sN1c(OslrM^B+S`KVSuSI0yFSEjLt|mk*sgrz<&gWBsEcHBT;m2n) zQS;t1vxw!N)dUG}TYGr`;i^e{6jl9>O8T)@e!B*r;|;up%9$4?6qXlHLlQ;(I<`@+ zXIu41ZT-#8;@8cVIh<4>(Ht}Qc3igvihv&M{SSH#gQlz2u4bAh>Jq>RgO6=RUS<99 zwy=X1s;uyl{=hRMiJ#|E>X2cEUX>tB(V;y@B_E ze89W@1B16iJa1sLkDV$@*u(vOT(>$)AV#pDvHZl5>CD&V5UI%VqM zoO9J!LethDSR5L%DZ$h?Kr);V%rYG+s=S4+s+Gh2}q85>h0Q1 zIm8p`Mcd#T%!fKtd*T)VV23yUC`QUQf6hO_{2oW+B2W#?9V>D}GFK9|xlkn8 zOp-KXeSNrXvU1$!a=DR8pRt%05f(N}IRd~f1T&r7~rkxHMIMLhkxJL=Ozh=Q$i6f_p^-I=< zrhl03%5^)vv^86W@E`R5IebV(_g1Bvr!U10d(QrACf`-af8G+#Z&>BM@_mDJs@CvP z9(-wz#I`K0NRArc+~apNv~|Ye9z3 z?n7bB)s^DH?Oc$$`4N5tn;lp+8`nF-kv;*1fAbSC6zm4p6mbznWXAjRH1dG0%7LhL zUI7cy9;&ga2Q}?B_xJ)!ByS?Deh|l66fSUZTaKV1?k=qgA}8|CNMk}85KEQn6m_C$ z=E=?g4#_T6;AY=zYaF!T>xbZxj&5K$x5tr@1J!|4a?rM{ml|^#P2+gWol?!5bO}?x z@~rLpp+L`Rj(YF=k~jqfsPv4^7Abz8B+DQUdX zrijR$gZZ3jnE!%hlUm`;f=c16gDv3o&w;wdXK8_JmPomm*d$0$;%C@{Z;Edw)usqp zD*h(w+l4W`=jyVDD3?AMilvqNj~CrmxzBY7~EgCm<1KWOETtg zB{UJ(JfWF(qt!RtA>>@?IowUwK98GoZt8(*?*E6dvyO`E3G#h_1OfyI?o4oZ_Yer~ z?h@SHJ!o+E!QEwW8Jytm?(XhyerxCLzJ0s@-8nsT&zZirs=KS|`>D_2IiB>5pOMy{ zG0f-nWbG~Z8?8CscD`Ktr`&v}qX56c*c>ryvoh`3Y6RkzygvM}WDCFOQT9Md z;neoDk>LRmke;{U4s2oRPxal#CO2c$?d?u|8GCH1-*M$*c`_I|pGM#2x$DbFeha45 zMd`^?Vi22tlHgilK(o9j6bf${RQA>630SlKQJkl8o-bq9j-7EbuJ;1uIPhkU^Z3%) zF~0Wm3vRuXqvORsZxwN-Np0=s?nK-tGmqKPzXedvsbHVzxx8~>tj7>Fx;Z^G_HK9` zo8CG;<`k3K*gpkReYx*C@yda^I`8V17yRTIUeyl4z~pR@mb3a<&dKSF--58;->eM@dEK``AWJ zT~#m!gSY^@iGq!W_9x-mu;$3lMa7=jIA}qtre%h?w_V8C*RCjTcoM555sZsxrRnt9 zfDq7Km9-Z3H_jn2k&u*k+6QE*CRW0G`#6yO&NW)33p*1n0pJYQ2r(YoH$3PenCER} zYtLM^8*Po(a*oDmijxKEssZ+12<~@!#^KAWybyR?gM@=O{thLIljTvGImMYM7dZ>E z7r86b6%d*)LYE(pVRGX9jv%Ftb+AI!si#=dmeQ=GCUs&`p9kVA76DWXs|IpU*!&`t zD>s3O%@_qIhB(?QsKQ70j%pd^9?UWT0lSUw71WG{L;h$MY9??Ky6|bVl3Jl)!3+4U zboLpd9oV&JD$T3$_E#9Uo4N2Zk7!%%I@o#3Mi2`dt`p{xoDY7`ina9Vr*(Nf%?BnA zw!+WW`W)nrq=m0-=&xFt{w~7SYY~u^J1G|f5tnt z&#L`L;1Q)+g;vU)K58lM+vrgt7i=0mAl)|VZ2 zU@_-;@rOAyTdYmo9$nV9)X0eRP!Yzp$TEi42^7}z_|)^vS=38H=VgG$WWiH;I_CMS^?d>H7b*tHb zIdi;qAh8X(VqmSZi!A>wycNtG=(>m7EE-Z8B}d;KNk0F9aw}`#pu?~VivDsWV_x`? za}cmK_x6G|10U`C@S%g?5%q4>6*X-lmk1NH$KL#&W9f>(c}cNoKZzhAfs!<%GC*D! zjsl>&F!kX$KEryOYAOC3CxWrUjTX&LD--?ckNf!;h+H(Vg}Pa2&LpHMt;R0xO7AyE z4d18PcFXm`oH&kXr z%c37t6)y*%Csp;8+%=^rZ&u0&oiupM@+s`)5+1%wCg zH|^LHuO-b~@gpYZgv3F)KsQ^Wi_R6_Y&lO0z2)`L=6JJ>F|A?y^FB38Mg!p@0a;eA z$H&G`Hh`y(YfrD=`kjvhT`KS_`)jeNZ&78z@4=^VIYx&J7|xQS7`Q%?L&Ej@u!gh0 zXXhl-zcz9BgQs`ik`0DuJnO5H=Oy;Zb$^&s9H&OVDaBX3En|XKq@Y>U7=(0}RISoE zB=GxeOy%cUmfmtS(3PsP$JQ^^xiWOCZy2(Y$0kjV&>y|bk0vJ&s@}kpDM=k z7n5(K^Tzdbf9UjD-6=Hid*|AYf3_0*oCoF9Z!BR!l*5C?)Nn|9u~9hoU?XqXD;E82 zSxSv=(FGvtY}d|doX3jQ=8Mu27n^;&;5l*MrMplM{(4%gX2{LF{?z+<^kHqY*|pkM z6hF;TCJHwC5{*U9*HzHNr8wk@HSO2P)%&lwAlnrT+;;$6(^@y`B2ZwxAg#_IOzh7Ti#+Ep4inpfAhvSND^(XN?RrWln=Mn*Tv&aDW1l8rm!pG=h~Uy>n?VV`Ex#d<*eP`7bOk*&9Sf!1T@fo7rs z%|1Fp;WoN~>CG(*rU_xe085_Ip-IP6_sJFh@buO$+Z1PXk`LDpevyS#QPRn1#YQA{ z;L9e{AXlWb`g}#6`M}Q#n*smaE-K#dOOH33QlWwvCb&g4$l~)rOM=DEjg-;78z*yV z27t$#6eS_&ZIqC~g>m!po|d&Hezuly&%aGw0ya^ya0|hCKP&M92O7KCId!6QU^KUe z3-q?W3a*;V+9p7(<59_e&0Xivk;nrXPb~6ho6YFjnOT~$w=DCmqI}!w*K~LJSiPvi zKg^}_S3n&em%KKoAeB!&=A;T7F^m9(>;yIYhrH7mpz9)p6 zd~-!oim~nnI@qkha1+_?HSB(auht)z>yJf7^y=2FyKX8Y%sEkVkv2W1ozB3&=8hD5 zC#tu@!pzw4CtyCcHvAg6Q$BK@?a*%A{gg(3?{q!I7!>r=?Rb>49{<)ZE!by(aJ$Cn zlBC7psEWREb~nn|0lZE1-cPU1%ualouDG1rJQN#qzAo`{=uvR4|2OcSdYAJgkEK>A zdCS&`(6wOPogXeB2|<+3`fInWHG@jMGy*W3l0n|83_z%JOpHC{oce)1It-NTP*eFGwQTF2qqTd4*^;9V z4%rK(!q2TT3u1M$6YcC1cOh!Up#Ei1&p+dR%vA(0z3`U)NtRL@(IO18bNw zm0R=La{Q;8B6bA9rxmcDXg9WX|EnIfp?SU-*L}WP^Vz`^sHLvfeBVDCn|aiH99%JT zZHuGnQV16*DONw1aYc%jK2_Iavoob%RQt>08?tdgv?rx?_uzd*=emWv0n{&APW(vQ zdE8Csqnv{aC`})yqPtByu2HHzHkWcOn_9M%q=N%FTpyr2B2gyi*Sh40G6EGHp#88~ zRgBOj(U)^k*2A01ncL1BPqO|^K~CawW3y4U6!|o$id`i+uBRUsA^goYi$0x}-n{Hb zuwkbZnrP??ft2TIe(;9p-C`Ke8)fUxl*xhWpTamyjftM?5Nj-_S+Z^6l)(l+Nt+o< zlX$Ivctq>Xz*4i3y!=R89BcTf64i=&)Docf2{>|9rC9i3eOR;62B{(FkZ{=jf`oAu z-)x}YQrP)%#4B9-{!jdO0)ba=M4%T;$J-ftgApAx%T%2GiJ6Ard@W8R!ACM= zT~6o$v)A>N`r~?(5RHEG^6i<#`P1OvcXC_bUnRI=<^gciaiD)6at`N5l;h~Yk0-JH z{$AcMz7(6|&Gj$&Q(J;6)V|32c!kNegmX4ItLZ4V5(`YMDo1v0gFztEPHDKk{W&X$ zM3bY~N571Q)fc~TDy==<}8lyv4tHi_!L;>8qFj_3NGPCH*1beD1B2ZxxGcy9Rzd2Dm^oJG*=t)(Ne0d`rAQv zaaorl-PBCKx9!ZnCwAHzv#wU03|<&c@Gg(4W7-sVG7f_l=tI>ij5N`G*cep~-XxQU zdXn^q$14`T&pWX4nL=~?;)uPh9!XE5D#0UfagqMM`_OB&p~%wZu|JJ-`Go$O z>2lIt1qCrN$#rZijf2^T1J`%Xa1@UNx}s|cb38}NN}$6#FliG+<@sJ${M*w#l!wOv-JFpHzvWZteJcVzWQr$v;SU~?V)z2n43t$S`(#Oy*= zu|fO(`WPeor+Sp72aEUq$;18_u`}n!vERFje5;*1%=~Qe6zB_wI^tY+RT+Uu*j-&>bnNou zBr*A#;b;qC%hQ2v$E7Bn^A1lkvyfXfmE8L)UN`Y@5w(PV;YX@N2MuoU32wA>%Hrx{{W7QgyEA2tX*zW(t}2RRBi`?93Csd_GXLq)X39UrOk^VEcSC% z>#cklF7`}RMN?_f9)ID<%Z_~z`;=pY&G(@V19f(n(7Vlx$#vhK{F;V9XLU~JepU*# zKvsn#(`dt$2#=JG19BYey*81Nk-@f*hi>i^Za>tp=Zw)!Vh~ zPgZXif1T<_5Tj+)?9=J$tGpGK!g5d+|O;>aH&{xhC}v3|Ow$&l~qP zbd>{n?N3uHWk)6^cyR9i^1XEIsg_X>^G$?Zg{_^pZyU~h8&5yUMy2Y!!?m@WIq8Sa@G zwOoE>dunUyGsAEyV0o&T6Cf~2jgLL--*UToJa{6#I9FxVcP^6qmv5i`brOKZpFW-` zF%%?RP*45di{7#s<+)@y2MoCEsxoJ5=KSn;2k_p1|WrxMEYDz$6%E*6dI5 z^uF^}(&LPDqKHd=J1=MaAQ`hFxp%!&Hq+53Y(=~RGfvh@OUYenj4{(TSq$vaBFj5~ z;gVs0(`8DdOSH>q;WS>2Ttr4h0X4k^f662ZfZqmh=hIC3zq0^-GE&;=Gh1(HY9>VW zRjvDFqIb+u)KZ0;m}{U;`8*}ey%!N2vFv)jbbYZV1zMy>xxfA%OsX)l`lXqeEQ23E zS9IUtaFQRDsj%F*QM1Z>@wOS@W^^x0H_k0eH_RO9#Id_ioGeyS7c@Hbsfk~F{Q}p< z%LTrYa3!`7Ux}P1(o=O-;Yz<2Njd%N@|E_Ne2FSoCDWZHdP`>8t8ZzYGGNOxc)Y|U zmsjVKdZ+}--_T_g@95!;6Ig8;C2poeMjnS91f!rqK?azXmOxBlACb>F>v@y#TJyGV zMyA8-oa4n3VfhO2Mxm9Tqvz;~`|n5OEl_B-&?abkU{=wu*o9jgK1N)2PxSSeE0NPJ z9a%6+bnJ%@;&ASg<{M*Ave;-m9QG{E{Vk!tHg%C&VXhtgFarj?4r(`G*GTaC}^}_uFNH>C)a4iAHG}3Fb+g( z>DV^&FSW=DaL)ISoNnkAvcq7FYd#tB!aGg_h;*XQLZ4$&mCQV{kSNs5E#*2)wVIi28Bv&ITEh>4eqkYCS^rrJ3(ef(kx z-BUR@qcVAWH1GTPPr<#2tY*%Kliu1=$fZ_C{2N&S5_VdE#?9Cr!s*7s>yx7;Lwe55 ztpKN7>mA9q8PVzVj%4w4KD)!6^+3)ES5s2NjOmAeb+!*$^o%qUbJFYl_j-TV>j`&3 z`v_GfK6eR=OO%H%K5VGqkB>J*HP2vHcAc^9$mQ#vW1P$0WDt00)l8`cU~X-qP{6Du>*uWc`!N^SY}Znu@xwdIBXk1^lf7@tbGcM_Og2P2N=* zKnfhsn{iKQt61#{hZ&&c_%12Q68Tj1I!1^_6z*|*pg~vaqRBRjXa2pR>>zaM+!DF0 z3%6PSmbpK1<-qaMge9qNn{D^TfZT9hvT~|?O2a0x-@PmYohAyQlxC7Adq_dR60hf} zse`ONqvt7_MvQSf7ed%H-gw-SUET&incg_NH8LKf)fYD&8bzR@fsa&{X2)P1`&;xthv&+dJO2jGn z8=Nu7Il|OSP6N|UD`lOBLf?D2Yvv4aeoZ4Eci;Y#UBGZ z(JXjfkwx2hbVP{ z0GmxS;C{^q#?$e@zv6e=)n`rm>0T;A>4vso4-y@%>pGSgY5tQQ^V6GVxO>CR8oK-m zMaD>yybJUSwfA#xPbLTo{}5FT?mgLFepsn6b)s|;N7&yAC3xlKqqQ;{QnITANpMc6 zRH?fq8|#Au#F2C8TmP`4Yy+8bJQ@20PLhg|R*WiT`w;K6z=AFGgzH}?Us{w4xicU6 zoxJe9*c_NVQ1JY5#Y$w{PaH(1ox2#?9E~E=1>PwhT!?<~4&eimPGn*=^y3` zo15-ieRCknKdUUXFabjCaUPl~Rlh+1BoYu{T4BL5J5F%KWH95tcYQW(k@K5E&KZ&?qf#9ucPxHL-p1%hT&o$5XR>vl6L~JV9g6|fOW&i{i1*GN8D^<1+yB)1H)WhuE{A4_+ZGIBs{7Y&= z)1{AMOMyz;xI*t0qLfA7EN@w?9j9dE-U*F^9;vv~f@I>)r;Ji*lS$I<46fF84R<~3 zKquFkO}N6r+E6~GL@wv^6D>uU4Q&;K+ zXD^rpBsS#V+I*tzHDB(H1w#>AGW=MY%_yA9VHPfGBNd>1Jj@~E5==LU(*f= zOcuul-?fz%Wg;Lu4w(_NB8Bw$mccVe2WjbuhH^Qkq?F6%+A)L;la-?$a-3=95|dG| z?z*(xu0qGu<(#Wll-4JnT3$lK76BWGJQh-7N3P`1U~yplR4pJAbSvPx&c4#@xPQMB z?)cp=nRs)J$ws8jKAQgyC)0focez~FDdJPYMK-T9@2_3Sipq^Xlh2DArt?nnB#)C9Ae{Y-LWaP7 zyS{iqee^^{C53|WRo#cK>NLze#F`^TB*wq7a2s{zCV+$aX>R74-(Tj)@nC*+s?DG4XwIJ%TgVbP91!W zC~|#W^5mBYl3eX$-fVm1w!Jp6%TuMd(Kxw_6(da{F8t2WUwt$o6hS#o+n{z3>S2*a zs(2A9r4^;+S0ewM+c-N0-07^9^x!X=qzq|3WiJy~I!3pp9-2ZFzR;6IJITT5p7-nV z63#C)wT8oR2;%ATAh_!_jX#byI8k?e4_Jq8HOF6PfbD@Ch-CyhJzIEVCoLlbaHIzX zUPF>A3jzd>k4~$K`1UU)Ei?>PmR|lokqb4W^oT#17v)ee#q@=BzjTaAe^=GOsIM@d zk(FofHg6+4t+R7+gQegQ41GeKsV`im%ur?qT=(Dgw^(9rEE2zT?>am#YJeDAxtt@& zm0g=iVX9mSzi2XHx@zdomjXY0&gl5i>X~|2mn2Z9X3#-3L+hvZiEC&l3Zh|*VoIZd*HWVML2WU_XFlf_ zsnn6Mw)_+|aRaHf{@L@Y_OdVvgJx*HBu9wH)@fNbt(4pVWv6leM%B6}3Z9X}R1_Hp ztqkJs4m+x7AiI<=hr#NM{nXJLQb=^zZZ)K}{*CX)G3a7d)x4KhnsM85^W903l|cOl z{#P1EdKZia zimnoGmPv@7)8x-6l<7p1blQC+Ejc*EQp3fkAYSI@`t!-_yU7D-!!t7*Vj{_dh~6sK zt*$ks(pszux|VA3wePF>YPpiM)&9G~$(FPTIB;n;`H4_&5?DkPMB)Q3aJpMX>2Sl+ zaJ3NL(Q2VgI#j~@SMMg%Ffo;jp3KSlVJ@qeY60H7jBN-kJ?OSWXCbBEK2K?YX{g?< zx>E7h$?B#VjZVp-LNU>|+(>f0q>53go8zO)`I?S#dA$Onhayg-wv>bO8xN0*dP*v4 zQ3A&zFG4M_b~ojVTT~cAF`C@+QipeIfsi*zB;UFWFC^fz?(Jr|Cw)^GJGA0QJ72EB z+8bM=RdMOv^$FX}N_xMx`){#TSTdL5Wj!#lO_4RuLuHgOQiT0kC7t$}tln@qSZmEr zts%n4w|pR8IQZs zu#(&k{$?lyH||`e=~a?v|7cx8!-OwO2XTZf)m_eIdDY5ue=;vccfE|cpoC$~8`DHu z&Esj<@XGp$s@?~E)*}2O2zR=0#t_kKitAj%QiM!{wtes>WlbYjN}aRrB>`n^rR+D1 zc5fj5YE_{+gW+bE721ax4Gwm;Wf1F+!7md{=$rCb>AwR}S+l!LJ%QzbBK=OVzXp<~ z-Fxv|n>fmq0Ov2e?q0R8T3+>*xGvQOK=lS`v)|$A_x*p7lc)E(iT~z|4s%B0yX7=PB(hF)GH#W19W?6I9?{c}G9N;(DcY=C*li*ZEpIDAIs@MR-MfgsG1**F zQbJ_yWIz`ymc?s-CR)Qw-Q!4Dhnkp~ymd}+JXawsr8%%%sqnTh`2L3xi*6#~kagWh z3qP{|cH`V?=5MTKVkLMJHiC$?e|?s>WVjAe4lt7#yAqGC?4A)Jf1ke+uP`50ftNG3 zpU-}AbLA4qLq&2(+$5yVRS_?nt~?ofvJMQ@{!0p&W zD{0pyW-GP1l9;_H+N?ZK{hIf5_Z+W{tV6T0R2^-Pz&m5E+PgGGFoNdU9}b!VQLcm+ zc?*k2?g+tMe#VcL9sWsL2xFhMDEAAUeheYR>Jj|F|9%~I-sNbssHg&wk)1tP|Kbf^ z({cBU=Zv~1O=q`E;?$5U2n ztJ25>a=z5VT}bR8{3byP&Bp`O`|D*tFd%;h>c=9b0h*x15OGee99x;ngP+e@Cqt8h zAOEuXL(ZO57huM_|Y1KhZY2w+b0(tN%tyj_S%YjU6HtX;mt5Di? zI^8#z{9WDM9Cmu4m|AbZ>);;xyl_yo2GUT8fqtHceENsFu#9XL+J@4WHZt7v!EVOY z7dljIY_;3+PO0Qe*!&DtaeR^RGK!5TT1!bSt))>H z;h4+3=lSjVg>v@`#bft8a>-n`m3sq%*vs&38h6`&C^I|bRrUUUt0G=RKkKgCuK^B? zx9Uh$+#>F=DDP3S>^_SS+CCKzn#y|>T#r;rgRHAE^cvo5U=*Z2iW9L;dQe6EQ5z0Z zwPTHGj0NHcZaWaJdHKitHc^kl|6-d8`xSk-=F!;CaEyvfBKs8ffw87@I_zl19_-_k zePmafL~8|eKZ>AbfX@Z(PpeV+9~aA=)tHt3n?nWvWh^s!gm9~kuiU4?eOxM*pyR80 zlU+^&_#0zau4|j(2gcWK7;H&N$r}kD#A^r8>2l*dtkz@2#J2p`Nckd}2oUN~+XG8v z_4JnmJ_Mae5zZ$oeKi*3^gfM#*#cTUMkRy0#S*^$YK;uzp~GuxjYL31B{D}~ol*yL zIk{>ft#HegN}2#9Qgn1Y98(SNuLF{8tje2~3B!yPhAy4Y^c3oQO!lk3Wt8(a?^c!T z0UH<`>t#Mo1y*DR`}TCtf%$F=;I;UX-h+b5-qrD>&>BQZ-og>J-fP&B$gCnoUa+wn zGV50AOi@~#4!7Jz2RAvPO*8C+8{&F2Oo1wS(nR%RtkCXt>Y3Cyp9iF#`qFI7utW1c zfu!?RlTZqcXv*&w{YDQxggFKxWwXZ2pZI9Xy$p51eE|mY_XV|IzI!(jAlFSl)2t4; z?#6%%Kf38qWFmOoEt;kmhBIA!#ACPkcs8?fxG*_Mc|`NefB$PJ>F4F|^3I9WRzcPq zpFdU_HQW5h1x$}>6KpVTGR=P;b5mtm{}Z#I+6zz71vO*_mSkJtrs~@W^5su%PEI(d zyyRyOsQPc#%MG)lB>=Ey#*NtAvPq@#)WyQvEC69*aWV4lw*G>8!l$AwEp59x zEgk1MGMr(Jr^S6fIoa~(5uA^ey8^eZP5Z;Zu?0Ly_|Q;#-?|SHt_^a_TiO9{{JglJ z431&=I5mPQ@V^U?A!-3Ong?mDRzF-3Yb-o{7?)8sIEIZ$9_*f#vO}(g*Mf^_Q$}sj z{p}bdv%urGQxI0|3>$R{B^FIId#CQ0Bn*O<@SA7eXP@qq-DWp#7+hMkYSuSw;Yo>u zsJas~yj^7vsn&rVVu!K__0y9@sX>X-=lDGYjZah$CLOx{2Hx7%l4(~}zOTnp(V?OL z6Kw7?36!pAzAZ!v00CHijiw2yCG8|67*1xKPx7gmjt4D$eB1YZGo_M1nGmyUr-|v3#WMpL8vLQ@(Gm-s{hT66w`)qlrtJ3|Zx${c) zta^;B!Q7Ru4Y1A}qMq9cUCZfhG|?SjAZ0~$;|}dg_IVu;yxG$W8W!~b3^w%dL}jX* zq)Fu|6&N#UXYJ=6Ew(MpW9-pU*URKx#XDTXo3X^$V*2GAcec|XKRuwbaNwAjFk)~k zBJ)3U;=XOiK zx=|3e4=E`rOkZE05LYh2kN4Gc1UxhUYItAyonV&+hfJ#DI_QU{IF%QsYgLk|T7 zRFC_!NC>|18=(p^>3@%Iq=F6#3R-Bg&*RvrfUJp$VV+$r2Tg2(iMwpQ43us7(Zt|LvT@L-}wf7pTj0 zhKhgw?Ef8I-bM3n@o?LOC0TV8EGf5Jm1+T)-mjm(Az`0@b(Sm57gT^0ob+EQx5PPW zzbiOg{%=IaZ(JWCvKvQ8(Bp7e5(_x+yDTkdTmkMcW!FS5#2&kBdXI7G%%LR^)b)eA-yd&EfQ9jxe0I%c61G$g&{({isX&?Mj0+ zs!0v%c^vrGIeopj^LD+_7BDn41X>St@$T)-hCuBg&^U1682*QA+hD??=X7%ulfni{ z=;U!J?%686tN_Z|vX&*MM5ENFYIR7;`}yg1Qe!|*Ht{t1>cv{Vu`J=YQDL6kbjYZa zMxj$e)eTqWJ5}?%z`HsNvZecF!(&} zs+|-7Ai2?yLkfjp3TkSzDXvfLp3Y+0R^=`e=Sd6$KVkT7tyX5aI4QC9yz6kxec%4* zwBDN?(QC1Z9jjK@9Ts4d5(}*9pvE!$KW{a}Vm3g;)fS^3qjO#c=ZMfAV^-495fQz< zZ`Xjf*SlqLIk`rDT?ih4+2uri#jXb_O;u?B=m4%10GQ&3FvB`W+ro@@KlN4-u;k~T(8hW2^e z5#gu72~I-q9VI=-b)EaLW6@O-D!9<-!nif5mOc@^(IG4(IGEV^S(bn&!9N%&{?+1x z$@Vn_3tK{(i$N+H@c{yK?bO!Qt@P#-Bpr9ez`!IGpjf(&z~XjraJT@!KZ7CQGGId> z+PeURI~WR4dT&JWo@I~yfrju#5Pctq^(KnsvS{*J8%3Q>`Uu>c3)|ZGtX5kvd0kE> zxEwIKSCV*;{=wn(_Vt;A)j0M-G@VG)GgOh7eZ|rnt!9l(U2@k`lfhMZL35x4j(KEs9SZOd)bQyB3=y(z%w%{Xx#>Bw^a zJ*x4YAMVlp6W95QqupgTlqTk#qV0OJo^JrTAl<;iB&U+5nhJa4TdYoN3}LKak_?)2 zOVESiE`rr^e9+%~j)TQ2d^FmshYaE8SQYu)>54CNGy%KZ>a9l9E+z^AD=*sGD|PfI zK3oMMZ=G9u93+igXx1$#B8^GT7636yYW`Y4Ypq|Qb$VxIGvinY^- z@wMbm6_tupL8?4xXcC$*1R7*6eG3x=6SFwUBolR$-IN7->ND)e#&SAv{okz^~Ue_KA>L`ueFub{qEg@*Dl;AS{^;%R?3@XE1IjR7`HQo zT|=a32JeY_=h<0E<4C222Vn&0LO%E^8h1#~NkHX|;d0Hh38gghnM%RScWUIS_m8bt zuS~8kOxmTi-+yx4S*`fj3gmrVf%GHP)xogW`}XbY*Uz6neuRdG^7s4x{a-$=NPSE> z2@B_?GS*lRb` z2%zSioSVdAg>DtUL@6*aP_AmgS#9JWf?%0k_h4y`z9S7P4i8VEkZ@2E0x(*C8JL!? z6Q(6{53S=zioy9sv%5O;7fQ|7@g$Wu=5mnjfTDkCueLtvY;z3H}@+#I!sc> zz7C15t}a?XI)!x1=W|G?V=DkfptD#ZkID1SiaO$DrExl)!d1#d`Z*AFl&Hu3usdw7{(LI>@?1B5c@PvLdI%69zKfR?B(hnKlCQ!7k>{kC4Z%5aPOYsk+lke-F@Y23X>~^ zN3$8#^^}v<(~eXIL%FmGZ^30D2a+aFQxnR&_O++6-)ifGI7+Pss1ncCCYB!4+ANwjbkY$?-5#&OqFubh(z6njHS1VvU~nZKA4VyQp!z zN>g!VH-jao6~8!L*q$R5vEpi)>$sNTMS!(}Zpx?U;2r!p8#ti5^Ib`fJAnkL{mz@?>K}Eaiwi-b>(2z`RmQYv~cOT7{GX?WCh$tOc)EKO#ubSV#+;#+gy_(%J3ulKPvNV>!OdK(ZX4w-@)9t6@eikDFppF_Y<7hURSSb!ns%*MPz=Yk!M*cKFoz z-LjYX>4eqb?rH$I=}HAx%qK@?HNIz9?X|kr7g$-Z#-mbXRYu;@TwANKWVvNZl}WI^ zlh{~L?ZhSZhc#6fptx0t&`F4e{*VC?m5+V&)saCxgnG7LmQ!Rg6pidGM(wFL;_+mu z5wO^?b2>cHnJ@p+Z`$oMTgrYgQv#da|?Pw->gMcNnwkv-1iF$#qrwt`?{u?0dR|WNv&3 ztK(>s(fLF3WB&!^W`(}l_8YS<$+Q}(!YI;oYQ?qR!5{UD?cLG>8t`}Xuc>RM#A7>- zMfNadCQyh(S%0{keal1R|J+vHC;q(==;1cBEoQflttUYla5?R+33orbaHk|^S*<_k zYI{6ub-Q2XWUlnJOwe74MCY72|9RP`_s{4%*GL}IwMlfIrlP6nj#~}Iypk3;>F-U> z_-Fy!S|4bm@iJGo z1=roU$pdsv)jx-KbnEi!Mey}zY1!?06?>yZLuvvgXS1?Aqwz_*P_(lpTGcHg$~GB-hb_q z4r~dd$ZN)q^*UgRIunfSUct8;lIvWZ&dP54rZY-(Os3i%P%xTmNnQ5sj~jxnvZCy@ zYZ|sDr;yE{&WKL3pV}NzU;WCjml!+DstVpPl!naQ3(V@u0!gIQgBLbZBF?mg*dr$r zL8)~8H)BnvCgH#*9g5jQwaVY4r|o8naX*|%hoZ3YEesyq)zO8<$jYv`*Nk(4M?-#w`1s4L_ZKmeIoGolbGj6bHz^1| zS1tMOLF?iJ@S;)0S)MmP9u53UmCNM>=k9Ek7IjytNHz!z2Io%&2edRbiMPyzpa2*o zLR}B1K8ZyU#QJzhq(Vw5iKPT`-;JB34I=4VFm$xrV3m8y|61Bd!Z{IY6|Y36g_ea-Pa|7RfAnm%rr zMA{SLNKfk4d(dbw<>e?CvM*b8=)Q2DW@>2+**RSDW;6ME__my5v_pbZ2|_5_7*)6! zfTjCpepf84lpQ5BIW)e7e|1vFgvH38eRulS%U6zfk6Kvyf`pjmCP9fbo4OiWXf_On z7jvbyM`;7Op}gJx{MxbT2n8iaOZM4p_qFT*U0qh>HJsk1J7*ZrdNW+<-tc+TururX zxO%2Rgpf*%;r#&&b%vMQ@fn?ALUWMxYNppI?E)5T{m=mpB-9*HOh z{%8f$$1aNq$1ExF3|DHPd$AZ(NrY%^p5sRus7KFzCQfAJ6#wD9)-NbuDG&U`bz9nj z>13j#G^Nq;tct*~mq9XUPclQ@(+YB{=AXtA+X4kzLC(`RK+W;>6m_K$udZ@m0UFBjK;-T%+!fBZa02SKN=?1%<)n z(;7VK&Y^V{7;}&G_^Q~wZ_jt9@lMUdZ;;B+xWvJ?76L`Qi2*p?JHS9pht5v^tXe5L zx7X*%4sXv00&Yc~uQLM!aFlYHBC1$G3GtS(M*=9U zz|+-M&XUPy26`H%lCj>_a*rZdjU%st&CSiwD3gXi7!)zD5T^RY-5qRM3b)h2*Q=|U zaN-x)S;!iMSnRHVCB*Pm&zN_8-j#M+*>u0@WpPM!o&I_Lxt2a`@%kI&BX7z=EVPpv$qVY>+A9cgF_%V!TsXy?t0PS?!ny&8iKpKySsaE zw~M>GyTkDBXS!?N?x$;}=Hso}b?!dvr@D)&v;eu9{u<|=pkqI0GlL?tcJO+PPRGTPmE_$60~Hz=gN3>ljjz^ zf7NN7o_}+*%vpBO=K`o%9~nlh0J6!jv=stW*8NSI**IhhF_V%uXUbrHh{8j&)2fJ{ zsz4R+?916cy2os)Ur{Ue3YVZQMXnfEn?K`@ND~xrUH--~ZGOICkd!<_b8DUc6Xxj1 z>gphV^S!d#b{-EA5rAUr3_~Ugu2qBX3QY00XTpy^UhgC=9QS~C5$##%!{fC3l0>fq zE}c2LTZxwiXZ&7+{xDym_rYyIH}qlQ07#aU5c|n5stU6pK5|O z2LzXrWjL(Tr@W@JshdI>-u3 z17wslQm#{TdBs&v`_kop&$r`{>nQ$#8hG>KXtE8yLF^R(E^8W9r7C{HI;G*KSfhfc z+EVf(*)Z8L$g1~Sr+(H`;Y*IRO9!yYkEKcB{IJZ%}-8I~>1`K6>Kb9ok3i0Ea%^Q`N(m_Cy(C zO5IUW@(xE`w%JL6&%7_tmAecs_M3F!O&cm9Vbpgz&1}=jOe}V*6XNZC9OG_lX1djC{nW`A8S}=dK|R9c6k4} z-D(3Wr+LgS&nJiB@t_!JD5!3~dSXW32^fD96BDV8AoT1&pKDhWN}RGR1Lmx%N#2`q z_TUoEWkGV<&m~E9P&he_vu&}*$ZRn2N#e-uBe&Hc`4)#gMIPm0hyYeNwm9YGCE(@i zeD%~>!a4F7+fiA@rGi?H8HJ+)Y=T^6jB63W*Ac<8`E3!)!a&4oZW!;(UiX#y_3@c> zHW<}_pbad_{kSM8guztob5$wDgO1``JG3mhspG>VyzzQ9X1JMCXwi@8G*++?b&d3b z5PL7dGm`lYR$-l-8~Rm90-CanQ8$81D1%yMM1y%6e#C9xB7}c};lc#p+9IcQ~!PJ<);d~PFz(cKByu;(M`9(d?T^JlvX^*mx;PQ^JmvA-1vUR6T7o48!hA4qf8X{-C^^v zsP1vPQ;R|j%K+owoly}mVB`aO8GQH|Ufe+cr{@dy6J$q>{Fj#%S*`qkVsOn^8B;(q z<$)h23n1w@;TvF>4( zmLCbIYvrv0;LD+2r)JPL(_7i|ss)szlHzf>Cx_GB(2;$%@#x5GI`H^AYs;KF9}!0( z3SN9bl8gyHj~*nnXIDWRd$~9mN}*{lv9_ zT==eRssh<(U4RO^Yp^QeJP4CG13J5B9=e~daI+`DFy9n?d%l8Xm8y_iD=Wx(x)aCL zObi}btm*3}j~ittw*$J~#}h?n)N`;)B~Ol6nv0$7%2%6=_RHf^6?Ih1u%+n_e|%u| z%CaUgM_NrgH^nHt!t0sc8kdbVLYZT%EF#=|BT2XByL~Hd%0#L2Z~RQ5iunB zLR7xG|Kf?ovE>HbMq(UAs~Jo(956nYRNC3slRF$DJ|%#*@;RpKS}^deLN@bTGS0_p zo>4Dz^2Z`EV_VV4V?u$hEq<~}yt_M*E_8U8l1O)z@BTDPZtb=_kPp}Ks2NP<@S4>& z4>+kl1?OT?=Ip77C=qh82cC;&j;WLqF2DTqr_&_&Y?lTIH8==`6y~|n*E;>cNtW;> zv)b|;(NVUHEaHv$k7iwnI-a>Ws&<^VnVin%;4929MW8AOwB`7aT$A<>d9ww$UC#cP zG~QE^%`vEA0H!2+{GnPbyjIypqQPk}l^)l)oR85TqvgC!)%ikVWe)1Oc)LVo+Uuwj zQd7D3R&pxZ;4=|UN#8j6FNl)a@?lV2UVY*4S1;#Q;qtvd5EYpnj&w?%9OFj&dU9kU zZ*tnoL4l*AiVw6YT~w?b-=lEqBNJ~)IuEX(xf%8|8~4Fdp`-AL=ua;otLyh5A#RD!sMP~unVyjT zt}5;85$ZaeYTQI?43PWHR;6HO^aCBq1#SVTD|(*l@``pt~W++Ky@C8#S(Fq zHKgRw4%I{R$ZEkA_DR&J*EWgi5YE}Vw64o{-nXVY%NB&MDzhZ-J#;_ux*1{MwE@rK9t^Z4TK^D8rk zzeT9HqrW^HhcwcL@~^ktr}QvdgsM<0+X# z(BZL9?_2Y*1c1_d^6&%NlKmZjbzhqDXO7J|Cgqn+cWvWo6EU}+EOu?RyvvM1{0f2M z^kx&G7};}F^L;;dh%Wq<&Ld%5z>UQrvvz{3<<^)dR$P{3moXr-o*JX-Z4&7%xb^+t z9)MrLGC!ICv6W<3=rV;xI>5M*1F>U;wZ)C`3OPLAl9Afkt8$GxfVmS!3H(;==Osmy z0L|l*uR9)_4G*slmZ=g6tW{0+g*tO&vjWHoy7Zfme=F}O=;3f?W}c3 zsa#yh-4ozC?N!f+-1U=Uj@w>gBY0b8dAdItQ=5HpWs6^BfrPCPC__#$L$_9-hH>th zv$M0yn_;Jr;ZYjO{v3FY?o#|9X?nrtOL{R%e4 zHvmBfyqt)G6%h)tJD#vqAEhiKoO1zePFYhJzI0WpWo z;tHs1!dMWqcs@o3PL7P*7PR^9UU<>Z`XAo))NYWbv6DNOF-BNFckMuOa+D{tzg2bzh@BxwW_=Cn6QyNDcD&cGloBwa<~YuNhJA z@xY_OcnAtui#VGKXgy5igUC{beiDX!M#Fu(ufNJao?&FLSg@?q_ID1?3E4!O+{v0w zet_7#t$5gdYT)K4p>vP=)vb7SVdr%!$+xr&hkDQKpC2}A9NI`TbFb5vuOi~beKe;N z-1g_a7>8mIKUN!1JyHdtbm^F{-bUWyT|Ibb{g$r50dFaX7v{wOsRaN(=*2QXO;(%AvAfY|H&1pPXy| zb^dhr_<%$m3u_hvZ_o273b#-LF$dG&zzr??D?!9?`7VbS@gtHg%etp|@a4uS?pJz2^fegUz$`;!q(B!ofiWxyHCBN7A zI&hU%p`NrX2v_IM$oBGH0xI4z=>q^!kvRlXjeGD3L=N~5OpNy00l5B%3^9-gB< z8zD)%K48dINEwhSP6H1CV~46OX*OB2G*j&0A9AW}j*BDBg#Cq==Cc@yFKTrVqlrmA zrz6Rs#B{{dmMOI2E0-nGa}@^yZtY~@(DXCGv$BA~$6q6-iuL7J- z525x9@@4j`bh^Nj==HisSqgIlmMG$tVDi7aBuY8FT{FpsbawX*c9qcTWEBj>z}|tM zYNNu1YeiBaQO+Jt8IbpK)kEBA|Kt{ELiecrPHc9*^Jr4J8}KVlZj((G4_Cr;NZGxl2qiV%2Tir5fWnF({rzTb z&yG7R_9_6JeZ1nR1iM>g&K>WuGd^ zdXnYl5%)G!_}Otja2l@LQCD!HmTj@?7g@5DX{^WTDb=OnK*uJy94NJ~*K0N-&S|9p zljPG0VNABL6wCWJSNb*I16fNE(*CZvzO7)3aoS88$oNq zu?25>ZUy6jVZStPD!yiHt7;KXRZQsd|EN&@3mWqP15S&bDMYRHGziLzLWGYVI`w)% zl2W_hVZ0U!Ni1iR&aWGRBj?v}WkvI&Wx~hBr7^zQ4r7pdVosS*Y{qMB+$E+kvp)C} zOAsUZ#)t3v@roVEnl;*KL{GUvb3v? zZ=B82tUax%Cul9Ruk7F*;^cazIqn6y-D)`x2v0I&eP$Pgq&kOu&ko3#;M8Kv!QZN% zc~#g*jXBb;cR5?$N*Ma}=>#e+^lrU6G9G9t?ds<49GzKE94?Ndw? z9mO7{HVd4-puMkGpxnKIwR4zrMoxNwC)w^AjK;uYRT3|ckBL*L|6>j0boc`u9bF&e zC{rE?j9LApV!$wvUwZKaZcnPZ67w&fek&3Z5+3o)0f%H@ZepWQGe524;B7z};Drd% zg^r&wA*PaiP%L$rs9vH_@B6EzQ+`V~$bvUQMI3wZ2UbBAaog#j+S8!7PCSgE$(nY z@T%e7UN2^IliFnXN`vpbktXB#j5`IGQ(c5WG!9gy=#)rs&9Qoy>)%02&JoI78Q~c~ z_r)(wE}6yb%}dU-V!AG1XQ+7)OlEs}CAvCkkQtGgI(>@Z^=wmO$^yiWdFN@VzDcvTozwYm8us6;YB2D#w7rlUCI@L z>%_jif8ir4bu8A-`v&DidRJM9K=_sG=Mb`zkkfh1*RTj&4#T_SxyRGGNdN}E%xaxf zQgSjDm6f_W*5~cUI7Hc$IpeOP>lP#p`|TSU-$8vxb6{YBQA&J=Xer&qD^`Tyf!^jk z0N(X9gf_Ru`8yncQgpSaqoPpeh6&&tGBD4%D#)_n+T_W0c!7 z%WIFAcd3g{Sn^9bec*{pTP`F6-V1n}t;uH1Ew-7>8q^+Ze}{;3W2?0LY=~qP(c1B; z$w+6qTZ#q}x`CTo=ElO<5Vfie#`o?96{59eggy$P|$+V1Nef5R9(bqNW}hlAYa=Q$g5{IuYAa?m)_T!7Mg(%JP~`fZuNf>bH4aHA9?{4aF{(q;eqhgq1E39-}Zam)-e z2KbEIc3eybot~<$H*%;8 z(Xs-gKN2X|0^k#~z8vH`yFz`mx;?iYtv?%Ilkyi$KxSElH zHm8NV8?*ZSR3QgIE6?;qnS<;`m%aM0FFbFkQ*p|ji@SO~S2we|+=!q<4UQO;m|f^W zx>?^ke|N64RDGtKGP7iJc!+P%^0Il&^km#J}i?*mrEgckk}@LDj4` z*Rwp@NO5X5Q;G#olEsE&rQb*k*P^`=yHSWmp(s281*j2^iL0i6RAk3^PT&WyGGc%NCy z6*^|9_hiVb+K}7q>Z-w)pp=NscHF)uJLV$52~1ql<9l1k(-ujQ%Ot0&5tW^9+Y`XiAWQ(btNJ4h>E)(QqPGfl)El;gfVUhPOqN@nYP(P;L1Y0SS5 zo+GW%r;j_kXum;R_l$Gep6SkaW@>L{bJ&&CZnhH|iMlcD4a&d2*wE8FEj?k08&yLJ ziXBNW_uMOwcj2879V~G8nyi@$o-UAx@G|j!S?WbXep5*)DPnj{=X8Ie66BCNCcKLNZ{vP& z-&Cn$$DFg%Qve1%v#+j>ShC$ul1@?7@KXBvs~2YbVd4?W3g+1GDk85lRCCF`ItY~T z*oxm5$c<8(~46WW@$9!!`RUG-3M*O6d-5`oqOnNs~Q;D;MFesn3js+q|Q zx$ai3FipLtwF0B6c#tfWn;n&S#jzHT7zv3{-X^u#ZW zi|;=eREvS0BLN0G2us4h)*7fK!uD;14zvQ=evOfjYm+D#rO=uwOa}KJoiV@}YdjK(+bb2mQZ*^Ou;So1Hrr7ZSp643D}YB=G;QUH$y{ zf<_X8$j1?Ha3R-l|DW3D3I5Z5n<-fMzxDjz|NQ^){J*UV@xtiB|8ua+kRcP_Edn+s z=FiKEx7IEU&xhK+DV`5xmVBZa z-~&3imb2w2(oK1#E`Q3WM90P|7Px$tB*X*-1u;GXFCS^*uXMK@y7cY4W_wX5-@N;_ zy~~xHC!f75Zr(Jjjx&o&Uck|m4rfnwt%sc^0(QO%uc5E2+PT;ZFVO33PA@}n)Y*{m z(7===Rc40=-+sCu{VfHevD)r`k)V)pI-Uj7X?-NRaW5&L@TaT=evaFAo<0P4RsX-QZLPx9T`Q4kaJNce6sYKqSXh1t} zf-Lo8SSa$f_lg`cu!T_I6wn z`5USEWRbP98gZk6O@aj3fDGGT`k*~C?I#x;?Q?}n=kdZ<#Of<`sB$yeqrES<>S<-p zdI|n51b#JA3SYXIP}HyOAqnmslpp6;OQkgYx_w=mV+p;Z?34|5euFhP9DH5JSMQRS z0~WF{Glxv%x5|{`3YS|hRJuJM6@6PB>76KMl+mmg@nCRz*YreZLOgGHeWueBx1Of8 zq2hgk5GEHRq2|Xo@OJjNK){&DRiENuiR(-;p+T*7%B^B=>&eG*oA?6S>HVPrG1^G+ zy&|Y__s-}^nr}u^NdM`+(4K!o*y@___fUXGG$DVrs$@#&&uMPV%ERQ9(2U z!b(dED|}(|qkjs@FD^jJ3UndBEh^b8l(a~y;*IxS<&5(%kJ%zVX|H9;W1k}IL!XN? z^-AQnJiWn3DBMq;CXvacS~72S1z0ha)vQc-(x5CDd`vSJ9{(KECA6Ypl_JTEEyj1^ zUUI@cx^#u>DTwOQ;xDxh_8fk}&asMWIN!Iny>j~dskNKkG=522b1--6wo`)ldd_}R z9*Gi4uGi0TPq#Ye!jh!Xw?KbyphW15S2h4~yCEXZ(1?7w&%gL9cv8CKiP#)HFtPJe;EUp5V>Ii2mBFmqi>~DXV)KOmG$e-J!k1)wA@>~6ltPRNrj`+sHy%Y|= z$EuU*S$B_BtJmT)lk%X5{@;@gx!Q9@J=lxs1_iZ5KSek%`jWx9t3Ny5lx*t(fXmA~ zrq)rd8MWgk@&<6EgAcJZ*OIOjd()>AAS{0mFc0P}V^A?dQYac+U8GT4xlRDxOIJ)U zj^E7;%rv2A_L+_@vf#mCGw6%1buzxqo{YbZrhNVR9l1;{@GS2wH8n*I+b!=ny`d)g zMPC~IAm3mnts6FT4eE%8oF-U^B~A&tPT?f4J&B>Jju0c;7xFemIVr@M3_MZx@y#1XMsqs|!y^_Mw1RO&;nPzlq=anP1atKrP-CGd4$^RrMsz)Pp^ z+EP7p*+_wWuioPMOSn5FOkM}8EvE;?5ymz_Jw-!Rkgf*Z>8mB*%(BXQ;nQqvN2raso$Q7RG2-`f0d{cxG@AM9w8TyI%OX5~#R`D2cr(C@zz+%yN0MIi-#cyvV9xrtT)GOJcra)37` zL|zQl7H80DxrXtkCOdLzs)8E?f}@FjnQ_W@O=%%NC%bh_W~JwLz-SUpraAVGukL0s zJT4!C%sexE@Okq5P`0}unXc3rmnNa!eMUu}tzvf*w^Q8^L+jVwi@y~(BkGM|MST8W~=904XAq~-r{c+Ro(-H_+F25`FZ8j5JpZSv5i<_|cJNYN_N) zP?uJC^cBQrdUWJ)-zz40rD#*OUARUw*n#d>e>8_0(@*gqxLdGb!K`AUDalBE95**15SvLZ##B36GhQBW7s9Mn*0=et?uvh=7dOE z$Rr{iSRg_!ns?#o{m5+P+m|*TvgC(EffNsYZqBnY_@P4(EOE177z&_6lk$7@(XVHa zmP#TuKS3Q!u9XbMWTe2!YUik!S7cTEbyyV+Y3dMqPV#cE`f7e5ELt0JwSZE?B7t2uc!sz1wtIDKth#A_T=jCtjom%qE zx=r`t9v4=tQG{9*(f}2he2Jwy7+*x<9xC8{xACVU25IZ1g~h)7g-AP6`#1h2DO@7f zZAT4Qw?TU<%I`y+QKmBk=bglM7U-(DTW0A`R8!s4gTR3yQ39K_Df)K;XYr)681?!X zGJAI6CvkLgYvIGqqhvuv_8Ce4f!Im?&qUVH(9l$gp>t%Tb;}8(el6l=1{r{^-V&D_ zQF-T>#g3$NJ@IQ+6C#lxtTQRoH-PGq@ia5&FNOu-_j)%O}|_h?t5K{^o9Bu zy^B5vDjy(oUBiz(TT{K}!|6k_)44;;Bn@56(Ysd>R6gsfs4nD>=c-dWq~4Adabgly zdh|8lNvwMI<#!(eFWKGxGTAYBlvs$iSz!Yn*5?DT0byvPdurq>}KcGs}+ zW~?DoJegemy~;`#L67no3CB2PK`jMK758QT8y}1hCe~}>snV7A-=DXy&m1BCW27WC zBI-D(JL>^R#u->Qw7I7wS7)prI9?3TzOrb0&pG2xH!o-86RR9Vo~4{&=%vCu=jq#rnFhyV$HbWpm9;%`bhDIG7%>*@1NB*Edsu9dc@` zk~)g*4k}>1+Ui)MQ|U%W-gmR<;m}N$s457L`|MuXmP`K2H)gc;abCu~aeOQZVHzly zM8j7O{>Qt~kU}VRbn}J;&~;Cco`lh-b`Yl?=Qq)Z8J25dSHi5)9l-WT3m&P*ePGg` z>U~NpycNZkT_KZoq4rivL`QajL9%%E(DVnCRSH_<6$Aa?4(mEs4Qu#w;1lPd5qALa z?TKai3@7waWeevOpUFxSeV#xs;MT%W2SRhyw-4lhkm+-SAmL zfOL1%ei=P3(bKOl*gzB1nf_d7XD*qnN6~^E)+nN^nep!M{#C|)JxcvStvcC-@q6J} zZ%~~GE9#3;u)3zdd9T@(AP#Pt021^2cnVgVSq%F3{|Ewq@PU7~#;rr#rX!g-Kucn> zPHq)&y~PgfFIlOcq=2+UlpCa>^DbPIJZ|wXx&hZTD-2keAgbko>8c75R&P$_2+I~b zlHC3ZumJ|SDn@#x*uwUEPYV8|*YuZ$Hv$q(|9uR79-h#(E~syB7rp}TsV0BomgJTL zAKG-2W4UK!(`6qKaPBgBPgch9peH&P=@7A{rsM6B_bLdR)jM3M2(zCkQ}Z>bEO=Ji z>_jp!-1XU5STlplXd0hhA4Q7k8`;9M);hw}rCv(&s!EJEk(gHEEoU{ku72}VNq(N- zk}-!8g?@v<7A-CtOaYjqHpMiG$@Morin2;C`DarJ+1<&B?e?Azb$Wj9oBw5E-Vwb4?;)A7g_2}e= zp2!Y(Xf;lFNLa&< zOVin0@Y7)L>YLvK9Ajv?l!HNI`0C>Ar-6%*WA8gGvHEZT6BAjzK6|ae zD^D^b0{mlwBkMLgY&~o`)#7M+Nu1BdB=Z-SWDCA3ll&{um#Ew6g8bDWF%p4Ja<0R` zhM(BxPtZv_F8V=^=-X%yn+s1uu-MfIN_kDhOzjAS-w2|fe0Qoz%i*u(`;R1BG4cUh zlCF1u(G<3Ys2RT-{?`g z>f$48{ZP07{L1M6onU9nizF2GN-SCa?6{S{SpCJ2@s%w$l0HC!j5%ZFRh{Hzq6#nk zNcob<HZYMpp{7PNRl;`{|kO^wg*flkwOq&p^2x3|bc%6c&OHUl;t z9U+JvsLs1Q=eF|mEFkEQZ}d2vXmM1w^4F^un9)x|ShzwUy&s#Rhi0ShZ3TJ1L68tKuK<4RJa845V*+Dn+l=LhstTL1>66)*uqR)VxvP1R|RMO|*5sUgtl;E2)Q zCV#vgYzCM64RjV9Ow}o&HsW;&`+s_{f4q{N=}Yz0%t}5!mR@@7B06o{hwP`!z8hl0 zIUB!Iqq=851PwUj8g_}7jo#W!KVlfoUPP5#WDRNz3|NZ4c=P>fI;&=+RfQ!Ze6r_@ zARWvtGZEI(0D)^41a!uPaa(kp@*omjg`cI``_HdfNq@4@6jbeS19Z5z?t3Ao`&V#P z@9Cl)&v~^!tp%4-ZkkRqa5=|19^`j+(f8lYlz~x4oWfM*4pY-nwI+%20M1We9^s2awPe0Y90XtPhlay$D z7$M5byjR@>Pqku1=r+(AYql+JtElhoC-q$%<-lDW4+=0ZutEMdu?L56GUlsU+>Wuc zYTzS9F?|XjxvZ|p>jJ8Lh|I^KC?2%)D-itS8THMGEB*PkyMz#+A^|CSW1In+<`D9oF)C8|2HJ0y4umMXC^7(xNhRvd$s5c|yZAJ{=+Ic?)Zqxl#4p zxdD4Z|A)i12Q0i`**u3!^fUAYrn!0wZi8_rWi4`uqvTN1%n}^NyfYED3&W6E$o}YC zD0$ttOZ#|2lT}*gOZ2fD=DYIn0)1M!oLLunmHM@l>Ix6=<*C8@6^gJ;3GQjq!Ef=g zUaq6iv`6bdcGX;;K!O~TLwmz?6t1$O0c>}`_s-ymXAED$*U%;jfxM*9WvV9Gw=D7=yGwC^ z4<~qMz#wuaq!sp_C1WI4X5ok#?I)+@wZca0fj+S1hm~RrV;c8qfX92J!P-#og>hfF zhQGWI8P$(%%q}7jwdM*#P#KfD5}Vo`k72$~R=M~ExgLypbNgg@|R}zAN9nrD0WJpS?Jjfa<~<3&KB`(GL2q26O!_0;u^Q z5FCyx@<$M@Osa(kv5#VQ{zYCBx+|E@t^0SSm)yW)UO>9`Tp2a4XiFXs@csl>Vi{jr zDroi$KI(4Oedmbdz{qZhyuJ6>yLkL1Irz1qCalJ5XYhI2a+iIr5KHb;v#&=QuHK&q z=3qU8a@^Jv(GO7Wde}CN1WT*Xeubl32#O-as z?EI`>{PlqVA6Vv6a^}F1NUeJim&OS_!Lj7DHyyA5;ICZ?%H!0>V(%6$>4@pL^S3O} zN9EVO4sG*bqU3jM&dv#k+jRi0AfN|3y#Y0{C?X4$y`LgfIdXF9gJ#b_#Wq#*fxrEM zgD7+35i*wsaeNWi^6616Mv5EeS}`}^ljX(o46c9Gaae3Vc9>C)@xRTEa~`OqU42iw z>FQ>EvMv58vcP11@u2JvXn#1?9?N*5mUa7m$0JV}it#(Lf*R%zou)H*q&7J=B>U?V zO$5a=bn)7Kr%|V-LusW6YAuk~t$!5EXS1{Wv&Hmfv;E zun>Zdhio`;NuC(&={(rPE#27LE#~+`9%1Tw8GQmvMpudE~9TP)XXs(GOB8Pc9d*o<=NKr7+v?Yg%dQx6&-=IWRdOtX!;Pwfmh$2H$rsJ)s^Qb?28s3t_A{cE5& zYD#yR)};aq!(qTzHg;7^MB*$iO&kR#SC=2JylE}-0>E>`qGuLwe0j! zP>QmeXb5IvmV=uouAbZ3-DVYE$^d*yYnq|y{E29-IMny(eGOmUDr}%&2>H>?fnd^b z+?VE?(jCr$=7P(3ABTLr^`0Z+8=dp!)l{S#ponZUDF5j()Jefs+XulM6V(js4&42E zTN3}9baC2EnFf37U6rR#>C?Mx_`=x5%N&_82A6k!5s#q=3Gh)Z5~}{r?v^|Uv!h8< z1=1qc(%L3LIeWH*i+hz`n1&n#?2zuR@J#1*22at@sCIM^b%gO)ZBGd)6kX?VtoHNi zf|;7Aqq}x+9G^@gt1jrs*_YUg4(}NlqJsTO!gm_i=}&=Q=wdU>`R!@koY_}y$Bo2Z z1DT9MLblLR`;JpU1?QmbqW>uRs8o5mA6xu5-^D9erKaa9e&Ar5YF2)VWMBq~YG88& znf0|Rz2GFrX{iZv6m0)Q^0W+MR~MK_yPTpR2gi+M)Lkg{$kl+S@uEgN!GI&wv08xt zXXGa?h`uRDZdrIS592QB_~A!@pCyUe`*wL|Z*;03!2SFh);CN2?uKY)BmJl*tno(= z$-j!Zbl|8=cBl&p;EsxLtUHCMY>q@tPuD6slKU&W+uYq@2lJ_cGlz>wf8u}io-9m@ zM4D}u9#Rx^UVm+*8qK)o)A z`2$TM;>?n0Dm$nJ{kzq+BfPHg!8)O=N_}{ShUjB=iY!Jo+NV~pKOc2SV5#bu4PwQd zk;}vYLHF0O0`K!IjXDZOXfqU`rtocKN0OwS*#w&*z}cZHem8nHZRo)2(JXir$+%MjaXHdn5=dnP6-(EXp9(%%hVa z4UY8o``w)O70l3Maaw;mLhU=5cCvqo6&*`TUrwO>H*5~=n;L6rbQgaZlKtX$K`r?5 z_$*&0cEyKR2zd4hAuEekRusu)!4*md`_{m30o)(h4kk zgK}PQwVbb>v?3HF@|0N_EwSkPuNV}h1|)6>p<`iT(b7R|a8fITl+SyH(-d4QC&PuIVGD>Zr9H?#d)d$OR2vdLS(Ov6&lu znSV9K^OQVArx(%1kn{5hEFBcfnIODnnu^@WKDOBs9o+L7Rab$2fM&YU{yj(>Uy`A)nc1tTQ@u}SHGNEXC74)4T@ZsX+t7L*EOG22KEL`inuB? zyyR_QxMXm0UyJ@mE#KKG8knyZBgqEjbaRVYEX5pN8`DIqFWpAla@~tf_GzUBV^`nz z>1#r1-1b*-zrho-KlgT-8Ms&sj<9otc&HJMX&weu7i4YMxvCmWz{pR%4a|;$Y-GCx zQ%T8Yrb}xTfTh8!i@+d|#MJr9As>2=4B|-QC^Y-5uU!?|b&y z=iYtq`vczlYJEe`&@*dwcXf4l)vv1h&r}yP%}1B}VTeR&u=mmt;@W@ckkk$n-{@V{ ztxFmqg`Z4GXjQe=mszcZ?R<^7h|i2(9`pPz&vEYX@J``@YAt?cuuB5*VPIpYnAU}1 z;Pd^)3{DJ_>osQ>9v?2c@hh@~K}qK*V8$<<8A7z_lJVk%BTQIMxThlFB+B70 zqxcWObE<^G+IpC`rJB;TO3&vRb?}!FqEeGuPt1c8wZ0tgjq-vb@i-symbWuo^$ZTv zn4#v5jt^M+iC01k2ZHB+k%zcHk4Fxk&L4cP`qbGR_hiCEf*hQ@8iU*Um8>bMUK)#+ z0}95?i7VP9mxL|}iII${!8>U%IEy7945o`v0TvDCn)G%ik)UikJ1PPA!=YnJ`+cH^l^<@jQM<~7Bh^> zX-_XnxRyk$mdiT3T1vdaj!P|&@cOKlce8iv9J=q&;0RE~i>jkZyDAP$a4)MADlb=1 zLU7=$NuBYR?#Q0d3P;AW+27U&AIxZAX)GNz$9(`AG0gI1l3lZR5bLOo3;nX_B0i^4 zae$5r)dX=51t@~DN6PSJp*KwOsD$1%1IGkF!8? zQ{JpB-!mlA&Mt^@t0uvvPmKncr95I#tr4Zr=#|z}PcY;)IETF|91JlpJcVk`@j&9{ zHWt`hOP&mP0_uAmJ+tePMBq;`08irTfRbIo5E|AiC6F@4;;S}VmJ!MqK4Z8>Wh?nYR0OU%yLHzK zIHfwP%vhr$_p#c-xQ^y}zRe3q zbzIo@v^5hy zQIw}-L<1mcZ5UnIYwkUr&6V(Sa+y~Tb&7BV5rU6aI}_{JQ7L4tpA4oL#9OQzhi z28Y^bbEmPX$)`u?nhvZ-_vd?>yG5w~)Yb!FQ0kb{fi?^{YluuuF+ociE9u?nBggD% z)Or3e1O;E44Y@xad>qX&{E}!EqHlJrAu~O=G%d%x*5hHZY4y>SDFv7#D}XFEwZ#Qe z&`2(0zbPe^do{pGg@9dRF%9AsNBvNlx zT3z2q?n(vYTuzPcbiUrOdV4`2Q&WhRcrYdh$?_L`Y_5CkLcR&=c}Il%D+V^P&F8vm zFvd!Kku;{23!7kn=^J{@C)ntUz#&LsxfO8@N#|@h9FWbgIy}(?KG8sx_E+JxMX|OM zSE{Yp<(6BQN3lj|WfZxfN)(b~R?$qaHG+O^X||Bq!UJRNad5{y@#1Z1;aumZVC+8E zZJOP0+}Br!+a1`))dC@SD3zE;`@}q@uoW@nU!Vd?g&ZuP{hG0TrwJ50x_f0TiSZCO zif)KQAGsbOM+Al2bs--s)WHD4!atmcP`U8^Gf&dv?5WHh8x5C9-8NS2muzx0V0Nu> zgL36&)>wW>DJC3MIC*udKQT&^)Ck}vq6!3pQ;HxJOI2Y;7BAT5g0iV+X&%T0N{RHg zGyHHUwa)o@FVpi}=qYZy8_X_~w`(atEfe2li4Zf1Ep#>{RYIkekDhyXDCJr%c+lXq zRS4^0?l6Bwh3-M_*7a7nrpnVJ=$*aBdaPcL)6rHWrE2L$O5i?!&bEQ3#Lr{*oWQS` z;MuzfZH|7H1$Ub2ZH|!DJAeMlQ%dcBydgY)=%BV+p^3g$DlW$7IBxCDC}R8ZO*~)w5D{?ifZS9aDw4X zDgF}Fo9)9eEeDyWn4WWL{Zepp?^;!^M7d=d)7U?&Eo35xaRGv4W~AGF9B*fft}cI8 zX*dfP8Qg9kynwmE(lKA`x0Nc_E!}&Q_d_!A)w^M=qP5IrFwP^^Z_da zE%OhtnTwjWL>LRH#85qTHg?|GxVDj^4X%lTc{-SY~XD7`nGK^rQvFo5|9gkliP^GAS5>6r$Y_g`47D8oXa&u8BZdPttn?gaW-4( zER*h`Ass!|W_sS2of^&w-gr(vo9&z~aLh^6=Ft6GEXtWQ4lgj?R+iH-bq|Dfy5rru zby*01mN-#GGw`r-c#+19xTw}{Z`O;Mko90kYJ4BLHaX)-7ETI>#xrI6jr3S$o4YAsQ zd+3CN1X^xYpfa70X@z}$v1a*KfwGD#EGwkVIJ$YPyY++o^j;AxEu})J=kqRP=XD?G z!I5M)L8KOi%GZq`gmQQ5;_C1n_ElUGYt@x6_4%i>&^lovPIax1r`A61VPMjtfrfoZqU9KFOp0e|woX%n!Ns$lTr*#Rn!EZt<_w!AYsIz; zE=;0_>B24j1tVUd@GF}5>?S!jR}WU_(O0CP{N_7=sCPOn10PbyDqB`r-q71PVjl#+WMP&-)V_}%)Vs3v>4;hV%B{9bp$w1MN!h;dzVGW~J_ zv4J3v@oC7ozWC|X>b1#D`zoOD>6S~MMGl{3wy3{AJi*d2$KmWJvn@XO^R{^~%;?nA zWYo|2fZ=2O?cMDR0bp)%`DZXNFcV_e*<|)87V@kt`HyR^XvpM4jwoWn@57w(1b~6a zodu4kyLnC&vtiTkFNdgdqg42bNXfK3jpdK7D$x(!e0izh#OCBeTF=7E=Sa2(8Je}9 z!CtJIk+i~{prCEMy2?y`3G)jbAKFh_3H6YwO`j|E)F<1YrfC%^P+dj8gPleM=hwme zG!M5uS4Jhf6VzP}mPJZ;(QZT|#Z$cXRWRY?)n#<#s){~Cvi581(3zojyatY_U27@~ zb0(qDcED%8`vNIGR_-NQX&r9a6aI0%!CBAZlVcT6N1E&vl{O>}wE3xeyC(Q4TV+?# zk2HP}MJN>mBrFI0>=c_e@s5krXY}0#3`!f9JyUUC!1d;s$`n-bjbb+3WUC*YA1;Ym zk?eEQ>3L-7Pc|d5+Uh>%!pfI_DzX^FDk;eF6;V@6?Ztu*HA`nW{p{|}8>`#QEV|=p z{Cy??*$I|6tay~&bs7>iK7j=>>{ya>EBJynwW(^96W%HOiu5$>E*oiC(do#Sp*O2( zNz3C-)em=Pn4^w?X2`{*=qUs8I&DNhHM>L$#D$H6=3ZP|oc4VhK_^}b$8auS49cGq z%Ur*fzSwoD0X3n>C}~AJJ;qVzoG@Bec!cwtw_Pk}Y&gO(|}URQa=m#ji?7@j@5V4>K^97Pa(I#Q%x~U>QXP()wBhdkS>gS}!h{ z%|iU*%T(Kl=(BoFC3yR>!(kY-ozTz2uh18|F$U^CH@C z>@D*(Iji$eMS&Pf>ko#ae(54ZrAT0qapaZSziseJv%hLCfiH+YX}TBM zx`u(HYFeUKw#+TP@ThQOQdc_z#5S%&Qmk!N!rf6J)g;KXBrvLpYntSl_Wh3ER9-Xc zAlH?n%@F>?A=`HQcAVZ?@_XQ^>dit(h%YE*kDO&ly_o@V!^iS!`g0Z|uw zYvOG&zyLMLYK2Zr)6LYWd6xvl45~- zlpoo$#4wn?u%T18`w%SI5|iP9Wlrp`7HgH>BNQ5$d`yEB_l6YD2tZv&y1@ks$%@(k zLRnEy$k&_YO>06=VYepisKhT|004uM`vue?)_u&?MM|Zw}Al}*58Zf9~WDkH|dk)zf^V>@CJ88CT4>Df2nsr2ZS_Nc~M(x>VE}s@PFLt zKi{T6f!AnfcurJg=7W(H{~wLvM2BRzT=ZLQaZ3*_GPg{{!NK{Rs;R~GCTvJqOgV)a zl-P-40_5*aYdfbRR*F?njAz_Zcqlq`hP}Pranb(J{*VD!uP3zOTX${0@jmjA@IE4$ z6DkYTL~bCo<5PmXcWEDk@FYy(ONV~cHchs#KQvE#kZ6A^gGnq$)$HNy)Xc36Xs|nC zG(3`uD_B`n;a*N%`D2=y#x9MaHV zx8xe>hEnFIbOI(p6rEU^;FI!pr;6UA!a=M?%fN&lNZhN|f;Kf0v8a2;a~p#yqCMsY zj=yF9I+Ek5+Fpdm(3nC!gbxqOJ^RuHS0|{If3!3myWyW(Iy-zLKPF>YtYSA(w)nHO zuW@E{WJE+?pEQ;m+b~u#5!A=Tprk`TOJF@BiR7G|9EDB?f-=Zs+A?~a8lGm-E!uFl z;kZ9Ghed=Zv$d-pWzUP2HE~Oab4}xp^;M3EGxQ6YX-P=~1c%_k0soQ}AaU`Zml+w@ zsr=oG7Dkd;A;IDAI010*aX;+?zwk`Q73#F{j{@G@yG95Op#rMkh}IM?!kch=%+@^G!}f+XA4B4))JB&-)ib z$vhl?u>VX5pu2@Mv3ei_+?pj3HDh$N@I%-X!Fz`AAM@t1ZLLGX}!2vokXldP1z$tIOg} zpgiiwYi(w!eN4sLR$vuL{mh#?0B=j2JDW<6WdfM52*|Wz{NmMRBi1r5&!vlR%V$8*s-NWj5RE!s_ce zPeKU^2~HC3shNY$*H^Fz2D^ZFE7)L%>EL>cq}m+P?_Vn_7_)~zX|UrB#KB=37MZ)# z@SRHDxoPptcZ`jVjccvtNT8SB&nj!fMH^vaU?^K|P1NIDmN)kD3~|8zU;vaqG?Owk zp9Ea_{7L^Q30-RmiR;z9RPj~@b{PVa3?xDsX=%YW&ld!eY=x7o?d?ObZcU}))4Bz?-zjr` zS*;Wa&o!1`&~Dg(vg2iCXYb?+q&lA|f3L{Mcqi%P@$z_+>3>KOwZnPH%;2BHJUsY$ zK=&W`lJf}0Vzn6uvz5q zJmG_#bcz zscCH%mLfSS#${?XaeXs34rSz<;B=lID{r-Jo8jXqCry8tv06V}X&TVW4er&;pJ6JC z^;SEuu7jI$iihq9>G2?0*Sl=3h-!wX3C8pg7qjwRX_`7@lu0 zcXD4areJ)w+BQP{*NFLky;o;f!Mit4Sg1BGCsDFk&Z#WPGg_N&`hZ&av`mDJVscCj zaAn1i90@27Uo>6I5`ovja+{6K2j=JJ^ur#i_OlQxA9CPg5uTyU9T79&iim_$1P1mI1bh%U-7_AtL-?MyCmP(Jz zwa?!wmuvMde!WG!%$dj?q#G6!Eo$)!RQy2&sG`O=OKA;wh$I5|l$1z!_x9qRs92Vt z7T4e_6&><=KG!orj#6qDby$?E4-o|L_IEMiasoJseiJ_AAFtUy>BuR65EA(BzY!Dd zV}U;ziOdA?%&rnEZo{o6KFBYT-0KVGTD{?q0iMY*PaU#m9t4LyHu=MjFg4INLLVjJ z(8U^dF!I)C%FxfBe+5>&T)@Iq8PjsKSj=0a6iES7PBk>$(af=$gNlhBG{xfQ$xiE$ ztIOIDWE?lps-LQPn9O!@!xCQzwUfpxpKlkWXxjLUz;$|vxZPnsY19fvRZ?g@=6iN! zECVSHRoCF@hL`+pE5^Ft-q!(MFEWI2W<4^Pk zDC`*H96I3)&U?9`;kY5`lR4->BRsR8d09LgB&tlnC~d!llC z&~IJZb;z%ElYaVI#Saa(YVBEQ9~LlGy;=c!HwqX9^qH(bZ@I67$Oh$)*Dxqgex*Bi z`I6%52<0PW-E)^+BnuCn;_BAJ(@3hFBhN{Cso#sw5OAUC2cHgK*q6JHOe~J45gGwb z;Ietd8>wvfdV9Ffj)#!P&Zc0eM1*@<9m+CVHgG&jIDuDu^o4IL>04Ks119sC`83{G zna^$UgrZ{*+azKXJq4_(74o|Aj@b-0%9aBz7LW$hd zY+eBERuB43WBzcdC4UK*uWA>=7VbPIl&dfHSl>=wvG4dR=S_s#dnyy>YODKB7|ONi zd6Z-`?wYHZu4=rp?LqbpBo%%ZEGhc5V5hRvuoo#KgWJOn=aZEq)Xh`R59AvKzlcGR}0R2>n)Dogx6*VDq$ny4>|l zU48`yGrmkbz%zOXXo%e=JOqe@mIXOVMbtc=)ojg^ZCnaC3cd{jpdm+sp zKjZzBEXgM9qjz%4V=>Cj&(GHD3g|s`=<9VbP5;#&r^DeeQxqpZmzxm54ta!nxUCIpQbGgeHs_K2ktMXXR$hq zSayeA!0woE$?=c7yqBGuG4%kR+MS&_my|6w2Gg9VZd9GHcV9Zn*_Vqe*t3l{%OOY+ z^cpYCx5TXjKFkgES?Nvv8rM`9>UQf~(t04=bt+S>OJM(p1H`lu_{@!ma}8QvTf?Y8 z9n}RV)J=``paU2SoeR+|KAm8O$_HHta5CHs!zH8h6HIBWIF|iiXrLX&&ES-DS08el z(YLmz)G@}EbfMDFuSUd+I+q;oz&@wM`*POiIx7G@_LK@R%q!B^$jj$ebvZb+vsVB0 zdG6faH~C^>YYUZ}r&HDQkt_b?7ns;x{=1PZl<8(N`ldr!1g^dhMrRMVY|S+!*osuZ z_PjCv-bKeI;y&#x!#2YEsb9%9pLsrA*WQ&hz}(g`^h~~oudqwT-<@ZA!tl-;xwa77R9xb-$gztACuN+Ki-kbs%utci&@Xl-8k)EF z;HZO0F$Bk#lj~0h^%cblNyqTeZ%N$K|&Gx%Y>&>_y1$YgoSGsd^G%;o`!1E!Ywe9|);mw-drv3&woQ*yFdL{V(IiAYH4=!0a- zj%=Ox%cM}ElY-=S+rlZ5(J4IM>GL4>DsyQ0%Z7+8au2)GgQ+f$W0|j|ger@?Ot1mK zN{x8^hTKFK&Yaleo6ns};1a|7tOyjc(u=cR?4U@0XLN&b{J%y=isC< z8^s2i&~{w06=AR_3xfg(2a`F{2oR&P;EsYBRu~zkaj=iTxFbLn;n=Z4VXuK%dLo)$ zsr@58hkHb+Di#?v>o`dD;(=iO=_{F?c*Cy)2eh8|1BqS>prinUelRUOq-Wg?HkQ<=Y1J@sJFS9Gr%|D{&rqtsxKF=GKd^3l!s~Q* z`x}V}L9ulVDldf{)x>PvpX`G5%dL7du;W8S3NbS)aEro( z#d@%&{j6HX?76~TTq;Zd>bxQ7-sH~JE0^dkB^Iud>X5Y7@cho@#`#bwPtJw9cGgxS zb8TOm>DhM}&opmLZ1WV|D6GJEp^XX^&npG7CXzSfi*fgdvcA;F76=V_ys)3#*oEep z20hPIJ#X0DdjX_*s6WW}N_%UA#hg9a1(W-T*PYQ&@I&v7@;tAnSAx|r(gLBM90Dw> z(F!<3Vsoq)OPH#zfSWNhUKvk`&e;rwO9`M9?uZ;fJA8a|R@v8vqx3i-m#qOUPi3(r z=j_doDV)w9a5k!v*Tl)KBOt16rBj*A_tN7U-vnqlhdO z_gfgwFO>->H}|@FWIPX3=-~-y7bC(1vU*hoeMyEDr@RjMn^8eMYvt|7Jc^7*BTwVk zCd_EarJWW+YYOkUk;8?y@60Q=vum*D?C}MaU#M!=yGC&KuM$Sj?`(KE@2YvVMelZq zw&dPicLtnyUzlKR-0j@$S~*wG?Lf!0KaOe--eb@q?*PcZ^*+9r0OV`#13J;-IihaB zUJ?(8XODw$Vw!N2>*)Z*1+6)SkyPn~KC&ccqnIQw@@V{S2GD69uWs7_M$Ck6F5s`( zYp&9y|JtIILTEXzDSBzo(!|6||Ae}QAPj$gPbIPrg!A!a2Ah_m!pJ|)poC$b)+|s0 zvY7C$w%n;Zn0{*1y=}FIn}S~PVJnvvi~X`o^D)hX>(qk-5js~|`2FW!Ci604%?~?t z*!sufV|{u4EVez_fQ`x_?XDn8bBx`YE_k82}f&n`AvStJ9?#Q8^APbuIXo!id9GZeTHI zZiHLhV)`?obAzJ?gwBUGO(@0Meqn^6xshu@k^E|rLwlo8;cdG39!NX2uU#xNwm?P5M6S zUdC1iA(jM&y7jJCKJ=lWEg{#fVEMM`@W6YNx8cPsK5UKu#6r+}tkBrib=9%&d+4_Z zbXbmg1V^??bz5HC(k{vNUPXps@ZbEHbVr|cug8X^>dmtL#)q$7r;gU6AG=-mGvskE zCEgPn%(@SK>Iuk4CU@yD+*>t7>g zw+4y~?bK=4Z0Oj!T5y&eYYoUn{~TJc)zwJbjdcmmv(5=l>k3U^Q(uczD&^@r_nWMO zR!%BRMByNUX?^OnmnRwLtJMn=g*8pc5co^syE-AYyrulZmWMcFMo!t<(GVJXB!ROb z!oDuw*fV(dw!IuX5YO{EPQeJZgbor-yS^*KqxsS#+#^-ilC~Kmey{C!pihr7gVD3O zRxNuHk-$aA0Oim^f6`xzU4}L&n6VY7igN;(s+GA;D$v^O5$PdSVkjDC*EoCiva@5> zb~{lX{&@rAxpH5;WG5sfs7Kd-M}yomoh*fxOfV=eGKkuMl-D`SDGF5732i`*V082@ z{t(`)Z_*bK%?n>Brqr&|{CxlM`Q?n17wake1o?A91#=yUPHCaOjq1pr;r&niYp zS89>cGfwoOS~B-etc?b1C^;Ep{s-yBgO~1wXU13}yySIMLTu)cQ&o7D@&Q^|7*A7H zRmxWGX9a!8SBJHaybtHui8uWpd1-GI<(?6Jx3#{;x5(W(Q7JeD6*wG{yetGkTQ?&) z@!j(BFB1A_5G4kffgGY@D$1AFlXskU{g3?PlWGU=(`j(;z}ncDWM}EMj`%DQFqwMy`zdTJDa6-p1t2o^MADJVVtTHGY48t)Em3fec85P*;F~@ z;23=j@ue5L3j~^i*MOqJo|at+6pZWWdhVBL))2X<-hTd}#fdRpL3a8$qy)*v>c8TW z@7V`$9a6#lL_Te#+j0i%=TpsUff@TngJkMksVdzuIwN)QNM&AekdR(6S@tTDOS6(j zxj*+w)R^sfbJIqXu>hjt(Wz;Tkk5pC5foVdIYJV`5!NNJ!lCfeq2frFL3D4T>dO6w zJ;$gx^&aVEi(5*$iuDC~v_3wqwRJhQQD#~%k7XI~LS>ICGW@tkyllP>ady>?X3H(8 zFmEvV(u->rd41@cQG1+FX&|-fI&P>Jc%g0A2S>bc%|SPJ zVNfnQhPgH=1V85Obknt?T0bdgCw+QmzgJjQh$NU;P$=3P4RK~_y~ZX-zN{FfkAVJ7 zpu;`%D0H7mh36Wh5Enlui2hQp9PK2fAs=ch)goT;FMsb@OKLky=dFS;>K}DbRxuo! z+RCc0=T~<`dUqSDnYYh~*-Urng2&d=R1Hn002@os=MRje@56(y)mt0~NtUwyLtK$9 zUuXtarA{P5;$#EsXIQ-3+)TN&!Y>BH^H+>HBE(S07CyUU7D9o%2@8NJwMY)|o>rynBHtUlMY3&4B&>Nze|%YBnGJXYH3pEvF`O z>cX{>8H-3WL90znMe0>kYW04fxCmG8g|(7CwiU71Yq7Wz;ON{Hhf^8Ra`jBf$1wQ949h6Qz0r?-Z47zp3F zu4zaDHHz&VJ)LU5mJz;1cpg0LnR1OD3`gf68anSJKTglAsCX#gAUg4@wA_Fr-PL0z z$Rzqip_hN2Z9TK;i#gkhoc?$n%BTo6ziQ;1ig zLr7FB5oM%(UwHS@+cTQ=sOtCI&)C!S-DI*woOEKw{MSb}6WhXs+Z_-3IxF8&|I{L_ zyN{2d{;6;O!@jqMHO*~P>q%HpdsNKqk$5+O>He@n$c8vhQpQx4HeI8zgY&+>ZPMHf zbrPvxwpZRXyT2Ss{F!2l8@JOT#svbQwV7tsnTa6j;Ojiyg)f7tL0Y-da*WCH`6Kz( z>NZ8F?#5D!^J!&|v#e5wCeX@W(_yQ}WMZDAxKR2{s&4Kgso+VdiPeWY^HRj|D>A~$ z3*5^H)VkinC%9)nEG%mVj<>P&Ry_uV(Ej7q=E+wbfX8%D;^X|#e8Y$@hGOs!CFK*p*D(-%myM+Vpmniy@tWE@3tZ-?l9O-=5Tg7wqcoj%7>105Bx+?9 z(UBwmDMRw!Qb%0tq4Wd@6bp)VdAtT}9ON4tw0naEXy1km(p6v(lXqXz%EOh8z80}3 zd}?!$8|>v-WB4+_4D@?m-sf4qIwn2lP5iE9jPfTz1| z2U(=vLV(tM!vhbm=UdZvM(~(`S|{7L;V1M((;w6!m3l|<2*1*JE4E7@_iiW7c+(CN zHdORM!irE5%9oRq@HhQiY?19jfXLVP-Ja0NPvpZ`wn z3f~;&ow#r8i!lMpc`zL?D&5I}&u%^0EOHD9@~*W>wBQ$lQDL8#4I z`iO&5SStpAD#4O zaoEYw5CoF?$z1KUHItGlfR~q-bRr|{7(WkI7d?*EzBB_v8``AC&={&-t65jlHY!RU zP&kz7wBhJUuQ&Nlra_2XI{^BX6{c28XJbK(sJHs64V*jthmLHDHMynJh9T*P(e|pl zT|Gy;TKvQ%q$&E?AD@O8&*IXfat|l{i!OiCpjJ&eTTCJf;Yrwx6Q>XvpVsnEZHdgB zMI=m6%%J<`9)IAN{^h5CJ?v&<<-p$h^X(&{rxFslb}M{pz}tHR?m>yp%oE$B4x_>j zN}gZnr(QNt>d*w8-{;bMsu@}s$}!Xp9@mIIp9N5|Wv?^e(cuaO(nWw_Gi7KEBq~^P z$83e(!~puz8)|8g{xl?{AiE;`MjT}Hfdh!{ANoPS1F$*YpI7ekacmD`Q;l0`M`J8$ z4*;!4p4FG>%8uD=H;ZjZa1qQ?aUJhcc#d_A;HGa%c#!vVfeNHAt;fuBrb@M?LyFs8 z9`~V`P#AAFl8Wh#3+al^XSWQt3&~A3_xVIjcUKM$ZTIe6bC$fABYZ^J6feCwF}Z_N zhRLAmec?V5uWvd?B7daZ8arhj`5n)p1uC7tg&>CL9=3dq3!>cVFd(^CGYHCsM(yrW zzoaT&A7-TlOvQ-Uh|}L>iT`u=C4%cpTCY*^p^i%~vq$lcoB2dNtkT1) zQ|2zH^>&)g`2w&MUcXWO8ZcT^Mk=Ntr z*5X9hgiAM!G{N|n!by6=fXGwi+;@E`cDp_WL&hWRvB=4~`7a_qWJ0*RAJqeF_X_ay z`&g}}VQ2!8G9{E0vjwYD%_

oNjsQ4$)9EB5` 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 diff --git a/packages/graphql/img/angel_logo.png b/packages/graphql/img/angel_logo.png deleted file mode 100644 index 2b8e98d9735d12362e055d0e3b08ad4e8469f885..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 35179 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

S84EC))vU9iGZ{0o1O{|9 zVd^17&SN9#F~CYh6Bg$Q%aXF+nhWD;PP7K583954s@ZJW2=T6X{Q0ggy*6$#{28`= zf4fgsT(=pslC#44bE8^S-C$-)+^Tpt9)4bIhDB4ReNdIn=k~_iuxFN?Vsd-PX{q;( zWj0z;=_jVZ4p}-05kgz`zIX{ml|I|9=fF?iYL2Ap6-xLQ_*F$%zI}Jz9q>0NuWL88 z0RYV+F~6E{7pl7t4cOV*NGo&28lskn5zi9U=qh`wq%%>Uh>d7?^^>p3;7h_6 zdcde_tstnj5)@ip0JVus4W;qg{#JeR_;LovV6q!%)t70!)UEE!_YuJ{14zDx8rIUr z3>Ik-QcCrav|j4Z0|>551$!SUwcZ8}fToymwVq@!rWW!2XuTFqnl$TiIL*XqGTjAx zrOjm?w?RyPhNMy-vt(zXwPU6iX^z@3^)gd0G1Z1fuHlPJwk7acrrI<098+&GC9$2D zdV#RFA%?b{b}Jg~tu=SRRO9Pjb-mPD!zocYWgoU&lW-SO?PCHPEhDg;@~d*7EV47} zoAy~X?`m3gHmr@_E*EBkFfpWWjlQb*84}o$Qv41yB^1lKgf|InW(U%4wV>RuIzu5$ zYXV!B1D8_5wgk2)XS#&IZUi32lQ07Ri=^UZvsn`ee&IO5TiHElX_|TwSbsW! zX9%23psdk{Y}HqR)*7(G&k`F(n5{7L=f(BL(F_-GLoto5%*}73>4l~== zq|K~Ge2ZO#egLTIzl3`G4hb&7OsN4n=K7exeFP3;>mR6xr1F~>Pct=UPAz8a83v4Y z2uVwo3F2#7rs2>UWa-58R#*T~RsV)o>Ln()AD{LPHIn23@Er?5|^S;vNJvpWU-E#1L8|)NBX| z-MW*@u7~2xw!qN(q2`b^N0b;eqven|7Z_SSR5Re0Ib`Q@aTASW*)292LOnzC^?@Pl zw(UK#Z^s5hU`S}yQ0*462gF)KsC%eM9}>OvVm72U72Mr^Zf#JgN2nUSpQbDJ(N+*x z46F3FxB!Eo$F~O)60}PkqxFi$gW0e#PkaEiusjqoWM~OKCKj`KV-5s|x`nDCG)$Ju zV%16@)v(`b!OpJ+#u5}G?hqF)qW>apT{@l=bA&!r7i!T*qWb8{eH-=UVmJ((`VZ6E zCieU-iE%yM6>=93b1bTNlufq{89%XQd&X4np>l6E+VISjX`fop9X zFBDCOC{jVHhGA zER);HliQgLlF%I-Z}(~0?x8E}z?~E{Z_CQME7fpnvJMoVZ+O`FmtHuBEkGM=96Zq@n^SD{bcP6yY0EN&PT@ z(gvr}w(TW}A#4)h+If-$OFOuM6d}|BZ3~lz)m)<`NsS7MCHM@9!*6npmV_Yynw6z! zeIv#R<)}GvFTeS@|dOGp5RkJpXTcoh{Bfka$v?D2>M=3aH z%hg&)-iGtF&}gpJ1bpR zq!rEDmzX|w)z8FqshO-*tx8bc1{k19-Fj0neyR&!&;3IC3Z$kYk)M+{jLW5Gz*Vsn z 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
-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%0AO+?lD#lvFW#-67!>~#M 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%0A~2!LEp*d8W+!nnpLqz?fPaG>y9Ki2=eidWa>D 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 diff --git a/packages/graphql/travis.sh b/packages/graphql/travis.sh deleted file mode 100644 index ac2bbd73..00000000 --- a/packages/graphql/travis.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env bash -PWD=$(pwd) -cd "$PWD/graphql_parser" && pub get && pub run test -j2 && cd .. -cd "$PWD/graphql_schema" && pub get && pub run test -j2 && cd .. -cd "$PWD/graphql_server" && pub get && pub run test -j2 && cd .. -cd "$PWD/data_loader" && pub get && pub run test -j2 && cd .. \ No newline at end of file diff --git a/packages/graphql/video.png b/packages/graphql/video.png deleted file mode 100644 index db4644d0e72c3404d3eeb2094e301c0f7cc903ab..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 234346 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