diff --git a/packages/cli/.DS_Store b/packages/cli/.DS_Store deleted file mode 100644 index 5d196f03..00000000 Binary files a/packages/cli/.DS_Store and /dev/null differ 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 fe8c9652..00000000 Binary files a/packages/cli/screenshots/screenshot.png and /dev/null differ diff --git a/packages/graphql/.gitignore b/packages/graphql/.gitignore deleted file mode 100644 index 49dff905..00000000 --- a/packages/graphql/.gitignore +++ /dev/null @@ -1,56 +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/**/shelf - -# Sensitive or high-churn files -.idea/**/dataSources/ -.idea/**/dataSources.ids -.idea/**/dataSources.local.xml -.idea/**/sqlDataSources.xml -.idea/**/dynamic.xml -.idea/**/uiDesigner.xml -.idea/**/dbnavigator.xml - -# Gradle -.idea/**/gradle.xml -.idea/**/libraries - -# CMake -cmake-build-debug/ -cmake-build-release/ - -# Mongo Explorer plugin -.idea/**/mongoSettings.xml - -# File-based project format -*.iws - -# IntelliJ -out/ - -# mpeltonen/sbt-idea plugin -.idea_modules/ - -# JIRA plugin -atlassian-ide-plugin.xml - -# Cursive Clojure plugin -.idea/replstate.xml - -# Crashlytics plugin (for Android Studio and IntelliJ) -com_crashlytics_export_strings.xml -crashlytics.properties -crashlytics-build.properties -fabric.properties - -# Editor-based Rest Client -.idea/httpRequests - -.dart_tool \ No newline at end of file diff --git a/packages/graphql/.idea/graphql_parser.iml b/packages/graphql/.idea/graphql_parser.iml deleted file mode 100644 index 07c18548..00000000 --- a/packages/graphql/.idea/graphql_parser.iml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - \ 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 b00840a6..00000000 Binary files a/packages/graphql/img/angel_graphql.png and /dev/null differ diff --git a/packages/graphql/img/angel_logo.png b/packages/graphql/img/angel_logo.png deleted file mode 100644 index 2b8e98d9..00000000 Binary files a/packages/graphql/img/angel_logo.png and /dev/null differ diff --git a/packages/graphql/img/angel_logo.xcf b/packages/graphql/img/angel_logo.xcf deleted file mode 100644 index b048a630..00000000 Binary files a/packages/graphql/img/angel_logo.xcf and /dev/null differ 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 db4644d0..00000000 Binary files a/packages/graphql/video.png and /dev/null differ