kanji-web 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/Rakefile +1 -0
  4. data/bin/kanji +6 -0
  5. data/lib/kanji.rb +5 -0
  6. data/lib/kanji/application.rb +37 -0
  7. data/lib/kanji/cli.rb +36 -0
  8. data/lib/kanji/cli/generate.rb +13 -0
  9. data/lib/kanji/container.rb +12 -0
  10. data/lib/kanji/errors.rb +10 -0
  11. data/lib/kanji/generate.rb +48 -0
  12. data/lib/kanji/generators/abstract_generator.rb +50 -0
  13. data/lib/kanji/generators/project.rb +155 -0
  14. data/lib/kanji/generators/type.rb +110 -0
  15. data/lib/kanji/graph.rb +1 -0
  16. data/lib/kanji/graph/coerce_type.rb +66 -0
  17. data/lib/kanji/graph/container.rb +18 -0
  18. data/lib/kanji/graph/helpers.rb +27 -0
  19. data/lib/kanji/graph/import.rb +8 -0
  20. data/lib/kanji/graph/query.rb +16 -0
  21. data/lib/kanji/graph/register_mutation.rb +43 -0
  22. data/lib/kanji/graph/register_object.rb +40 -0
  23. data/lib/kanji/graph/schema.rb +17 -0
  24. data/lib/kanji/import.rb +5 -0
  25. data/lib/kanji/instance_define.rb +11 -0
  26. data/lib/kanji/logger.rb +10 -0
  27. data/lib/kanji/repository.rb +53 -0
  28. data/lib/kanji/templates/.gitignore +11 -0
  29. data/lib/kanji/templates/.keep +0 -0
  30. data/lib/kanji/templates/.rspec +2 -0
  31. data/lib/kanji/templates/Gemfile +14 -0
  32. data/lib/kanji/templates/README.md.tt +12 -0
  33. data/lib/kanji/templates/Rakefile.tt +113 -0
  34. data/lib/kanji/templates/app/mutation_type.rb.tt +14 -0
  35. data/lib/kanji/templates/app/query_type.rb.tt +13 -0
  36. data/lib/kanji/templates/app/repositories/repo.rb.tt +7 -0
  37. data/lib/kanji/templates/app/schema.rb.tt +21 -0
  38. data/lib/kanji/templates/app/types.rb.tt +5 -0
  39. data/lib/kanji/templates/app/types/type.rb.tt +26 -0
  40. data/lib/kanji/templates/app/views/graphiql.html.erb +24 -0
  41. data/lib/kanji/templates/bin/console.tt +7 -0
  42. data/lib/kanji/templates/bin/setup +7 -0
  43. data/lib/kanji/templates/config.ru.tt +2 -0
  44. data/lib/kanji/templates/db/sample_data.rb +1 -0
  45. data/lib/kanji/templates/db/seed.rb +1 -0
  46. data/lib/kanji/templates/migration.rb.tt +10 -0
  47. data/lib/kanji/templates/spec/db_spec_helper.rb.tt +23 -0
  48. data/lib/kanji/templates/spec/factories/example.rb +9 -0
  49. data/lib/kanji/templates/spec/spec_helper.rb +61 -0
  50. data/lib/kanji/templates/spec/support/db/factory.rb +8 -0
  51. data/lib/kanji/templates/spec/support/db/helpers.rb.tt +13 -0
  52. data/lib/kanji/templates/system/boot.rb.tt +13 -0
  53. data/lib/kanji/templates/system/boot/graph.rb.tt +11 -0
  54. data/lib/kanji/templates/system/boot/monitor.rb.tt +9 -0
  55. data/lib/kanji/templates/system/boot/repos.rb.tt +23 -0
  56. data/lib/kanji/templates/system/boot/rom.rb.tt +37 -0
  57. data/lib/kanji/templates/system/boot/settings.rb.tt +10 -0
  58. data/lib/kanji/templates/system/project/application.rb.tt +35 -0
  59. data/lib/kanji/templates/system/project/container.rb.tt +13 -0
  60. data/lib/kanji/templates/system/project/import.rb.tt +5 -0
  61. data/lib/kanji/templates/system/project/settings.rb.tt +8 -0
  62. data/lib/kanji/type.rb +62 -0
  63. data/lib/kanji/type/argument.rb +12 -0
  64. data/lib/kanji/type/attribute.rb +14 -0
  65. data/lib/kanji/type/attribute_definer.rb +33 -0
  66. data/lib/kanji/type/class_interface.rb +156 -0
  67. data/lib/kanji/type/mutation.rb +13 -0
  68. data/lib/kanji/type/mutation_definer.rb +43 -0
  69. data/lib/kanji/types.rb +11 -0
  70. data/lib/kanji/types/callable.rb +30 -0
  71. data/lib/kanji/types/type_interface.rb +43 -0
  72. data/lib/kanji/version.rb +3 -0
  73. metadata +538 -0
@@ -0,0 +1,14 @@
1
+ require "graphql"
2
+
3
+ class MutationType
4
+ def call
5
+ GraphQL::ObjectType.define do
6
+ name "MutationType"
7
+ description "The mutation root of this schema"
8
+
9
+ # Add your mutation fields here. Any fields generated by the CLI will
10
+ # be automatically to the bottom of the file. This object type will
11
+ # be invalid until you add a field.
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,13 @@
1
+ require "graphql"
2
+
3
+ class QueryType
4
+ def call
5
+ GraphQL::ObjectType.define do
6
+ name "Query"
7
+ description "The query root of this schema"
8
+
9
+ # Add your root queries here. This object type will be invalid until
10
+ # you add at least one field.
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,7 @@
1
+ require "kanji/repository"
2
+
3
+ module Repositories
4
+ class <%= config[:pluralized_class_name] %> < Kanji::Repository[:<%= config[:pluralized_type_name] %>]
5
+
6
+ end
7
+ end
@@ -0,0 +1,21 @@
1
+ require "graphql"
2
+ require_relative "query_type"
3
+ require_relative "mutation_type"
4
+
5
+ module <%= config[:camel_cased_app_name] %>
6
+ class Schema
7
+ def self.call
8
+ GraphQL::Schema.define do
9
+ # This is your schema definition. The lines below have been commented
10
+ # out because QueryType and MutationType are invalid until they have
11
+ # fields. Uncomment them as soon as you add some fields to your types.
12
+ #
13
+ #query QueryType.new.call
14
+ #mutation MutationType.new.call
15
+
16
+ max_depth 10
17
+ max_complexity 200
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,5 @@
1
+ require "dry-types"
2
+
3
+ module Types
4
+ include Dry::Types.module
5
+ end
@@ -0,0 +1,26 @@
1
+ require "kanji/type"
2
+
3
+ module Types
4
+ class <%= config[:class_name] %> < Kanji::Type
5
+ name "<%= config[:class_name] %>"
6
+ description "Replace this description with something useful"
7
+
8
+ <% config[:attributes].each do |attribute| -%>
9
+ attribute :<%= attribute[0] %>, <%= config[:lookup_type].(attribute[1]) %>, "Replace this description"
10
+ <% end -%>
11
+
12
+ register :repo, <%= config[:application_class] %>::Container["repos.<%= config[:pluralized_type_name] %>"]
13
+
14
+ create do |object, arguments, context|
15
+ resolve(:repo).create(arguments.to_h)
16
+ end
17
+
18
+ update do |object, arguments, context|
19
+ resolve(:repo).update(arguments.to_h)
20
+ end
21
+
22
+ destroy do |object, arguments, context|
23
+ resolve(:repo).destroy(arguments[:id])
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,24 @@
1
+ <DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/graphiql/0.8.1/graphiql.min.css" integrity="sha256-M21BwIduyMmxIfyN2SOwMUdtgs/5QfTy3YCqciXGNbA=" crossorigin="anonymous" />
5
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react.min.js" integrity="sha256-Rtnfi1MVZAj3v+eDeFjh/iAXo8//D0zVKql8fjVLCiM=" crossorigin="anonymous"></script>
6
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react-dom.min.js" integrity="sha256-uzKwYuH50DHzDYr3h/Bnpv7C5QJNUjHEpVmT3Xuq3ww=" crossorigin="anonymous"></script>
7
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/graphiql/0.8.1/graphiql.min.js" integrity="sha256-3e+07H0vsK+FE6+00S2TdS8xZjq3yrPHtyUlFMs3+Ck=" crossorigin="anonymous"></script>
8
+ </head>
9
+ <body>
10
+ <div id="app"></div>
11
+ <script>
12
+ (function () {
13
+ const fetcher = function(params) {
14
+ return fetch(window.location.origin + '/api', {
15
+ method: 'POST',
16
+ headers: { 'Content-Type': 'application/json' },
17
+ body: JSON.stringify(params),
18
+ }).then(response => response.json())
19
+ }
20
+ ReactDOM.render(React.createElement(GraphiQL, { fetcher }), document.getElementById('app'));
21
+ })()
22
+ </script>
23
+ </body>
24
+ </html>
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "dry/web/console"
5
+ require_relative "../system/boot"
6
+
7
+ Dry::Web::Console.start
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ APP_ROOT = File.expand_path("../../", __FILE__)
4
+
5
+ Dir.chdir(APP_ROOT) do
6
+ # Set up your app for development here
7
+ end
@@ -0,0 +1,2 @@
1
+ require_relative "system/boot"
2
+ run <%= config[:camel_cased_app_name] %>::Application.freeze.app
@@ -0,0 +1 @@
1
+ # Build your sample data here
@@ -0,0 +1 @@
1
+ # Build your seed data here
@@ -0,0 +1,10 @@
1
+ ROM::SQL.migration do
2
+ change do
3
+ create_table :<%= config[:pluralized_type_name] %> do
4
+ primary_key :id
5
+ <% config[:attributes].each do |attribute| -%>
6
+ column :<%= attribute[0] %>, "<%= config[:lookup_column_type].(attribute[1]) %>"
7
+ <% end -%>
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,23 @@
1
+ require_relative "spec_helper"
2
+
3
+ <%= config[:camel_cased_app_name] %>::Container.boot! :rom
4
+
5
+ Dir[SPEC_ROOT.join("support/db/*.rb").to_s].each(&method(:require))
6
+ Dir[SPEC_ROOT.join("shared/db/*.rb").to_s].each(&method(:require))
7
+
8
+ require "database_cleaner"
9
+ DatabaseCleaner[:sequel, connection: Test::DatabaseHelpers.db].strategy = :truncation
10
+
11
+ RSpec.configure do |config|
12
+ config.include Test::DatabaseHelpers
13
+
14
+ config.before :suite do
15
+ DatabaseCleaner.clean_with :truncation
16
+ end
17
+
18
+ config.around :each do |example|
19
+ DatabaseCleaner.cleaning do
20
+ example.run
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,9 @@
1
+ # Define your factories here, e.g.
2
+ #
3
+ # Factory.define :article do |f|
4
+ # f.sequence(:slug) { |i| "article-#{i}" }
5
+ # f.title { fake(:lorem, :words, 5) }
6
+ # f.body { fake(:lorem, :paragraphs, 1) }
7
+ # end
8
+ #
9
+ # See https://github.com/rom-rb/rom-factory for more.
@@ -0,0 +1,61 @@
1
+ ENV["RACK_ENV"] = "test"
2
+
3
+ require "pry-byebug"
4
+
5
+ SPEC_ROOT = Pathname(__FILE__).dirname
6
+
7
+ Dir[SPEC_ROOT.join("support/*.rb").to_s].each(&method(:require))
8
+ Dir[SPEC_ROOT.join("shared/*.rb").to_s].each(&method(:require))
9
+
10
+ require SPEC_ROOT.join("../system/test_app/container")
11
+
12
+ RSpec.configure do |config|
13
+ config.disable_monkey_patching!
14
+
15
+ config.expect_with :rspec do |expectations|
16
+ # This option will default to `true` in RSpec 4.
17
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
18
+ end
19
+
20
+ config.mock_with :rspec do |mocks|
21
+ # Prevents you from mocking or stubbing a method that does not exist on a
22
+ # real object. This is generally recommended, and will default to `true`
23
+ # in RSpec 4.
24
+ mocks.verify_partial_doubles = true
25
+ end
26
+
27
+ # These two settings work together to allow you to limit a spec run to
28
+ # individual examples or groups you care about by tagging them with `:focus`
29
+ # metadata. When nothing is tagged with `:focus`, all examples get run.
30
+ config.filter_run :focus
31
+ config.run_all_when_everything_filtered = true
32
+
33
+ # Allows RSpec to persist some state between runs in order to support the
34
+ # `--only-failures` and `--next-failure` CLI options.
35
+ config.example_status_persistence_file_path = "spec/examples.txt"
36
+
37
+ # Many RSpec users commonly either run the entire suite or an individual
38
+ # file, and it's useful to allow more verbose output when running an
39
+ # individual spec file.
40
+ if config.files_to_run.one?
41
+ # Use the documentation formatter for detailed output, unless a formatter
42
+ # has already been configured (e.g. via a command-line flag).
43
+ config.default_formatter = "doc"
44
+ end
45
+
46
+ # Print the 10 slowest examples and example groups at the end of the spec
47
+ # run, to help surface which specs are running particularly slow.
48
+ config.profile_examples = 10
49
+
50
+ # Run specs in random order to surface order dependencies. If you find an
51
+ # order dependency and want to debug it, you can fix the order by providing
52
+ # the seed, which is printed after each run.
53
+ # --seed 1234
54
+ config.order = :random
55
+
56
+ # Seed global randomization in this process using the `--seed` CLI option.
57
+ # Setting this allows you to use `--seed` to deterministically reproduce
58
+ # test failures related to randomization by passing the same `--seed` value
59
+ # as the one that triggered the failure.
60
+ Kernel.srand config.seed
61
+ end
@@ -0,0 +1,8 @@
1
+ require "rom-factory"
2
+ require_relative "helpers"
3
+
4
+ Factory = ROM::Factory.configure do |config|
5
+ config.rom = Test::DatabaseHelpers.rom
6
+ end
7
+
8
+ Dir[Pathname(__FILE__).dirname.join("../../factories/**/*.rb")].each(&method(:require))
@@ -0,0 +1,13 @@
1
+ module Test
2
+ module DatabaseHelpers
3
+ module_function
4
+
5
+ def rom
6
+ <%= config[:camel_cased_app_name] %>::Container["persistence.rom"]
7
+ end
8
+
9
+ def db
10
+ <%= config[:camel_cased_app_name] %>::Container["persistence.db"]
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ begin
2
+ require "pry-byebug"
3
+ rescue LoadError
4
+ end
5
+
6
+ require_relative "<%= config[:underscored_project_name] %>/container"
7
+
8
+ <%= config[:camel_cased_app_name] %>::Container.start :rom
9
+ <%= config[:camel_cased_app_name] %>::Container.start :graph
10
+ <%= config[:camel_cased_app_name] %>::Container.start :repos
11
+ <%= config[:camel_cased_app_name] %>::Container.finalize!
12
+
13
+ require "<%= config[:underscored_project_name] %>/application"
@@ -0,0 +1,11 @@
1
+ <%= config[:camel_cased_app_name] %>::Container.namespace :graph do |container|
2
+ container.finalize :graph do
3
+ init do
4
+ require "kanji/graph/container"
5
+ end
6
+
7
+ start do
8
+ container.register :query, Kanji::Graph::Container[:query]
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,9 @@
1
+ <%= config[:camel_cased_app_name] %>::Container.finalize :monitor do |_container|
2
+ init do
3
+ require "dry/monitor"
4
+ end
5
+
6
+ start do
7
+ Dry::Monitor::SQL::Logger.new(logger).subscribe(notifications)
8
+ end
9
+ end
@@ -0,0 +1,23 @@
1
+ require "dry/core/inflector"
2
+
3
+ <%= config[:camel_cased_app_name] %>::Container.namespace :repos do |container|
4
+ container.finalize :repos do
5
+ init do
6
+ Dir[container.root.join("app/repositories/*.rb")].each do |repo|
7
+ require repo
8
+ end
9
+ end
10
+
11
+ start do
12
+ db = container.resolve("persistence.rom")
13
+
14
+ Dir[container.root.join("app/repositories/*.rb")].each do |repo|
15
+ repo_name = File.basename(repo, ".rb")
16
+ klass_name = Dry::Core::Inflector.camelize(repo_name)
17
+ klass = Dry::Core::Inflector.constantize("Repositories::#{klass_name}")
18
+
19
+ container.register(repo_name.to_sym, klass.new(db))
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,37 @@
1
+ <%= config[:camel_cased_app_name] %>::Container.namespace :persistence do |container|
2
+ container.finalize :rom do
3
+ init do
4
+ require "sequel"
5
+ require "rom"
6
+ require "rom/sql"
7
+
8
+ use :settings
9
+ use :monitor
10
+
11
+ ROM::SQL.load_extensions :postgres
12
+
13
+ Sequel.database_timezone = :utc
14
+ Sequel.application_timezone = :local
15
+
16
+ rom_config = ROM::Configuration.new(
17
+ :sql,
18
+ container["settings"].database_url,
19
+ extensions: %i[error_sql pg_array pg_json],
20
+ )
21
+
22
+ rom_config.plugin :sql, relations: :instrumentation do |plugin_config|
23
+ plugin_config.notifications = notifications
24
+ end
25
+
26
+ rom_config.plugin :sql, relations: :auto_restrictions
27
+
28
+ container.register "config", rom_config
29
+ container.register "db", rom_config.gateways[:default].connection
30
+ end
31
+
32
+ start do
33
+ config = container["persistence.config"]
34
+ container.register "rom", ROM.container(config)
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,10 @@
1
+ <%= config[:camel_cased_app_name] %>::Container.finalize :settings do |container|
2
+ init do
3
+ require "<%= config[:underscored_project_name] %>/settings"
4
+ end
5
+
6
+ start do
7
+ settings = <%= config[:camel_cased_app_name] %>::Settings.load(container.config.root, container.config.env)
8
+ container.register :settings, settings
9
+ end
10
+ end
@@ -0,0 +1,35 @@
1
+ require "kanji/application"
2
+ require "schema"
3
+ require_relative "container"
4
+
5
+ module <%= config[:camel_cased_app_name] %>
6
+ class Application < Kanji::Application
7
+ configure do |config|
8
+ config.container = Container
9
+ end
10
+
11
+ route do |r|
12
+ r.is "graphiql" do
13
+ render "graphiql.html"
14
+ end
15
+
16
+ r.post "api" do
17
+ r.resolve "graph.query" do |query|
18
+ payload = JSON.parse(request.body.read)
19
+ result = query.call(
20
+ schema: <%= config[:camel_cased_app_name] %>::Schema,
21
+ query: payload["query"],
22
+ variables: payload["variables"],
23
+ context: {}
24
+ )
25
+ result.to_json
26
+ end
27
+ end
28
+ end
29
+
30
+ error do |e|
31
+ self.class[:rack_monitor].instrument(:error, exception: e)
32
+ raise e
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,13 @@
1
+ require "dry/web/container"
2
+
3
+ module <%= config[:camel_cased_app_name] %>
4
+ class Container < Dry::Web::Container
5
+ configure do
6
+ config.name = :<%= config[:underscored_project_name] %>
7
+ config.listeners = true
8
+ config.auto_register = %w[app]
9
+ end
10
+
11
+ load_paths! "app"
12
+ end
13
+ end