rails-graphql 1.0.0.beta → 1.0.0.rc2

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 (137) hide show
  1. checksums.yaml +4 -4
  2. data/ext/gql_parser.c +1 -16
  3. data/ext/gql_parser.h +21 -0
  4. data/ext/shared.c +0 -5
  5. data/ext/shared.h +6 -6
  6. data/lib/generators/graphql/channel_generator.rb +27 -0
  7. data/lib/generators/graphql/controller_generator.rb +9 -4
  8. data/lib/generators/graphql/install_generator.rb +49 -0
  9. data/lib/generators/graphql/schema_generator.rb +9 -4
  10. data/lib/generators/graphql/templates/channel.erb +7 -0
  11. data/lib/generators/graphql/templates/config.rb +97 -0
  12. data/lib/generators/graphql/templates/controller.erb +2 -0
  13. data/lib/generators/graphql/templates/schema.erb +5 -3
  14. data/lib/gql_parser.so +0 -0
  15. data/lib/rails/graphql/alternative/field_set.rb +12 -0
  16. data/lib/rails/graphql/alternative/query.rb +13 -8
  17. data/lib/rails/graphql/alternative/subscription.rb +2 -1
  18. data/lib/rails/graphql/alternative.rb +4 -0
  19. data/lib/rails/graphql/argument.rb +5 -3
  20. data/lib/rails/graphql/callback.rb +10 -8
  21. data/lib/rails/graphql/collectors/hash_collector.rb +12 -1
  22. data/lib/rails/graphql/collectors/json_collector.rb +21 -0
  23. data/lib/rails/graphql/config.rb +86 -59
  24. data/lib/rails/graphql/directive/include_directive.rb +0 -1
  25. data/lib/rails/graphql/directive/skip_directive.rb +0 -1
  26. data/lib/rails/graphql/directive/specified_by_directive.rb +24 -0
  27. data/lib/rails/graphql/directive.rb +31 -25
  28. data/lib/rails/graphql/event.rb +7 -6
  29. data/lib/rails/graphql/field/authorized_field.rb +0 -5
  30. data/lib/rails/graphql/field/input_field.rb +0 -5
  31. data/lib/rails/graphql/field/mutation_field.rb +5 -6
  32. data/lib/rails/graphql/field/output_field.rb +13 -2
  33. data/lib/rails/graphql/field/proxied_field.rb +6 -6
  34. data/lib/rails/graphql/field/resolved_field.rb +1 -1
  35. data/lib/rails/graphql/field/subscription_field.rb +35 -52
  36. data/lib/rails/graphql/field/typed_field.rb +26 -2
  37. data/lib/rails/graphql/field.rb +20 -19
  38. data/lib/rails/graphql/global_id.rb +5 -1
  39. data/lib/rails/graphql/helpers/inherited_collection/array.rb +1 -0
  40. data/lib/rails/graphql/helpers/inherited_collection/base.rb +3 -1
  41. data/lib/rails/graphql/helpers/inherited_collection/hash.rb +2 -1
  42. data/lib/rails/graphql/helpers/registerable.rb +1 -1
  43. data/lib/rails/graphql/helpers/with_arguments.rb +3 -2
  44. data/lib/rails/graphql/helpers/with_assignment.rb +5 -5
  45. data/lib/rails/graphql/helpers/with_callbacks.rb +3 -3
  46. data/lib/rails/graphql/helpers/with_description.rb +10 -8
  47. data/lib/rails/graphql/helpers/with_directives.rb +5 -1
  48. data/lib/rails/graphql/helpers/with_events.rb +1 -0
  49. data/lib/rails/graphql/helpers/with_fields.rb +30 -24
  50. data/lib/rails/graphql/helpers/with_name.rb +3 -2
  51. data/lib/rails/graphql/helpers/with_schema_fields.rb +75 -51
  52. data/lib/rails/graphql/introspection.rb +1 -1
  53. data/lib/rails/graphql/railtie.rb +3 -2
  54. data/lib/rails/graphql/railties/app/base_channel.rb +10 -0
  55. data/lib/rails/graphql/railties/app/base_controller.rb +12 -0
  56. data/lib/rails/graphql/railties/app/views/_cable.js.erb +56 -0
  57. data/lib/rails/graphql/railties/app/views/_fetch.js.erb +20 -0
  58. data/lib/rails/graphql/railties/app/views/graphiql.html.erb +101 -0
  59. data/lib/rails/graphql/railties/base_generator.rb +3 -9
  60. data/lib/rails/graphql/railties/channel.rb +8 -8
  61. data/lib/rails/graphql/railties/controller.rb +51 -26
  62. data/lib/rails/graphql/request/arguments.rb +2 -1
  63. data/lib/rails/graphql/request/backtrace.rb +31 -10
  64. data/lib/rails/graphql/request/component/field.rb +15 -8
  65. data/lib/rails/graphql/request/component/fragment.rb +13 -7
  66. data/lib/rails/graphql/request/component/operation/subscription.rb +4 -6
  67. data/lib/rails/graphql/request/component/operation.rb +12 -5
  68. data/lib/rails/graphql/request/component/spread.rb +13 -4
  69. data/lib/rails/graphql/request/component/typename.rb +1 -1
  70. data/lib/rails/graphql/request/component.rb +2 -0
  71. data/lib/rails/graphql/request/context.rb +1 -1
  72. data/lib/rails/graphql/request/event.rb +6 -2
  73. data/lib/rails/graphql/request/helpers/directives.rb +1 -0
  74. data/lib/rails/graphql/request/helpers/selection_set.rb +10 -4
  75. data/lib/rails/graphql/request/helpers/value_writers.rb +8 -5
  76. data/lib/rails/graphql/request/prepared_data.rb +3 -1
  77. data/lib/rails/graphql/request/steps/organizable.rb +1 -1
  78. data/lib/rails/graphql/request/steps/preparable.rb +1 -1
  79. data/lib/rails/graphql/request/steps/resolvable.rb +1 -1
  80. data/lib/rails/graphql/request/strategy/sequenced_strategy.rb +3 -3
  81. data/lib/rails/graphql/request/strategy.rb +18 -4
  82. data/lib/rails/graphql/request/subscription.rb +18 -16
  83. data/lib/rails/graphql/request.rb +71 -41
  84. data/lib/rails/graphql/schema.rb +39 -86
  85. data/lib/rails/graphql/shortcuts.rb +11 -5
  86. data/lib/rails/graphql/source/active_record/builders.rb +22 -24
  87. data/lib/rails/graphql/source/active_record_source.rb +96 -34
  88. data/lib/rails/graphql/source/base.rb +13 -40
  89. data/lib/rails/graphql/source/builder.rb +14 -22
  90. data/lib/rails/graphql/source/scoped_arguments.rb +10 -4
  91. data/lib/rails/graphql/source.rb +31 -38
  92. data/lib/rails/graphql/subscription/provider/action_cable.rb +10 -9
  93. data/lib/rails/graphql/subscription/provider/base.rb +6 -5
  94. data/lib/rails/graphql/subscription/store/base.rb +5 -9
  95. data/lib/rails/graphql/subscription/store/memory.rb +18 -9
  96. data/lib/rails/graphql/type/creator.rb +198 -0
  97. data/lib/rails/graphql/type/enum.rb +17 -9
  98. data/lib/rails/graphql/type/input.rb +30 -7
  99. data/lib/rails/graphql/type/interface.rb +15 -4
  100. data/lib/rails/graphql/type/object/directive_object.rb +6 -5
  101. data/lib/rails/graphql/type/object/input_value_object.rb +3 -4
  102. data/lib/rails/graphql/type/object/type_object.rb +40 -13
  103. data/lib/rails/graphql/type/object.rb +11 -6
  104. data/lib/rails/graphql/type/scalar/binary_scalar.rb +2 -0
  105. data/lib/rails/graphql/type/scalar/date_scalar.rb +2 -0
  106. data/lib/rails/graphql/type/scalar/date_time_scalar.rb +2 -0
  107. data/lib/rails/graphql/type/scalar/decimal_scalar.rb +2 -0
  108. data/lib/rails/graphql/type/scalar/json_scalar.rb +3 -1
  109. data/lib/rails/graphql/type/scalar/time_scalar.rb +3 -1
  110. data/lib/rails/graphql/type/scalar.rb +2 -2
  111. data/lib/rails/graphql/type/union.rb +7 -2
  112. data/lib/rails/graphql/type.rb +10 -2
  113. data/lib/rails/graphql/type_map.rb +20 -7
  114. data/lib/rails/graphql/uri.rb +5 -4
  115. data/lib/rails/graphql/version.rb +6 -2
  116. data/lib/rails/graphql.rb +11 -8
  117. data/test/assets/introspection-mem.txt +1 -1
  118. data/test/assets/introspection.gql +2 -0
  119. data/test/assets/mem.gql +74 -60
  120. data/test/assets/mysql.gql +69 -55
  121. data/test/assets/sqlite.gql +78 -64
  122. data/test/assets/translate.gql +50 -39
  123. data/test/config.rb +2 -1
  124. data/test/graphql/schema_test.rb +2 -31
  125. data/test/graphql/source_test.rb +1 -11
  126. data/test/graphql/type/interface_test.rb +8 -5
  127. data/test/graphql/type/object_test.rb +8 -2
  128. data/test/graphql/type_map_test.rb +13 -16
  129. data/test/integration/global_id_test.rb +4 -4
  130. data/test/integration/memory/star_wars_validation_test.rb +2 -2
  131. data/test/integration/mysql/star_wars_introspection_test.rb +1 -1
  132. data/test/integration/resolver_precedence_test.rb +1 -1
  133. data/test/integration/schemas/memory.rb +3 -4
  134. data/test/integration/sqlite/star_wars_global_id_test.rb +27 -21
  135. data/test/integration/sqlite/star_wars_introspection_test.rb +1 -1
  136. data/test/integration/translate_test.rb +26 -14
  137. metadata +22 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8f87cbf32964de3c167e807e029be76418ab377ac1510027ebcc14e7a7bed8bb
4
- data.tar.gz: 56174d0ec5e0b681531b534c2c549bb24c994d8b9ea3c08afffd18c139400dc8
3
+ metadata.gz: 3c29232c14870c44aeab62fba29beda42f8f99a8047bf83f717149e6fc2e5d7c
4
+ data.tar.gz: 196468f3151958620774998650fe7a5f70e0b3204fdb5a028b31c634d21a9cb0
5
5
  SHA512:
6
- metadata.gz: '098a9f12e0a9ced37206a4abe195e6d01d52aa9d7c0a0870f7cfe3b583859cbe7a097fdbc113802691ab3e34179391406aecfce2358c6bd9806b63a24d53e0af'
7
- data.tar.gz: 1160b336ff4af0306aebf0779dcee046d5d13772ff41bc56e1ad0a3087eaba4a9988f08144076720f8868f0873e6a6dc0cff80470abd958fb6dfb593a32b252d
6
+ metadata.gz: a17d0f98a0473afd6d221d98b967068ae9d97da363e44e92817729e23a204510768c72bed50a858816e9d7eeda8b0fcdefe83c56d9782e8abe06d71bea6e0f75
7
+ data.tar.gz: c4258dfce30c7aedba8a3f2c1a9a6c20b0eca30ae520888efac8dfeb3f5267654d74e2992b9794bdb892a2f84d8f1be68d6d71e637ebaa48ee780d3b019ccf25
data/ext/gql_parser.c CHANGED
@@ -3,22 +3,7 @@
3
3
 
4
4
  #include "ruby.h"
5
5
  #include "shared.h"
6
-
7
- #define GQL_SAFE_PUSH_AND_NEXT(source, scanner, action) ({ \
8
- GQL_SAFE_PUSH(source, action); \
9
- gql_next_lexeme_no_comments(scanner); \
10
- })
11
- #define GQL_ASSIGN_TOKEN_AND_NEXT(source, scanner) (GQL_ASSIGN_VALUE_AND_NEXT(source, scanner, gql_scanner_to_token(scanner)))
12
- #define GQL_ASSIGN_VALUE_AND_NEXT(source, scanner, value) ({ \
13
- source = value; \
14
- gql_next_lexeme_no_comments(scanner); \
15
- })
16
- #define GQL_BUILD_PARSE_OUTER_TOKEN(type, size, pieces, scanner, mem) ({ \
17
- gql_token_start_from_mem(GQL_BUILD_PARSE_TOKEN(type, size, pieces, scanner), mem); \
18
- })
19
- #define GQL_BUILD_PARSE_TOKEN(type, size, pieces, scanner) ({ \
20
- gql_set_token_type(gql_as_token(rb_ary_new4(size, pieces), scanner, 0), type); \
21
- })
6
+ #include "gql_parser.h"
22
7
 
23
8
  // EXECUTION DOCUMENT [OPERATION*, FRAGMENT*]
24
9
  VALUE gql_parse_execution(VALUE self, VALUE document);
data/ext/gql_parser.h ADDED
@@ -0,0 +1,21 @@
1
+ #include "ruby.h"
2
+
3
+ #define GQL_SAFE_PUSH_AND_NEXT(source, scanner, action) ({ \
4
+ GQL_SAFE_PUSH(source, action); \
5
+ gql_next_lexeme_no_comments(scanner); \
6
+ })
7
+ #define GQL_ASSIGN_TOKEN_AND_NEXT(source, scanner) (GQL_ASSIGN_VALUE_AND_NEXT(source, scanner, gql_scanner_to_token(scanner)))
8
+ #define GQL_ASSIGN_VALUE_AND_NEXT(source, scanner, value) ({ \
9
+ source = value; \
10
+ gql_next_lexeme_no_comments(scanner); \
11
+ })
12
+ #define GQL_BUILD_PARSE_OUTER_TOKEN(type, size, pieces, scanner, mem) ({ \
13
+ gql_token_start_from_mem(GQL_BUILD_PARSE_TOKEN(type, size, pieces, scanner), mem); \
14
+ })
15
+ #define GQL_BUILD_PARSE_TOKEN(type, size, pieces, scanner) ({ \
16
+ gql_set_token_type(gql_as_token(rb_ary_new4(size, pieces), scanner, 0), type); \
17
+ })
18
+
19
+ VALUE GQLParser;
20
+ VALUE QLGParserToken;
21
+ VALUE gql_eParserError;
data/ext/shared.c CHANGED
@@ -1,11 +1,6 @@
1
1
  #include "ruby.h"
2
-
3
2
  #include "shared.h"
4
3
 
5
- VALUE GQLParser = Qnil;
6
- VALUE QLGParserToken = Qnil;
7
- VALUE gql_eParserError = Qnil;
8
-
9
4
  const char *GQL_VALUE_KEYWORDS[] = {
10
5
  "true",
11
6
  "false",
data/ext/shared.h CHANGED
@@ -141,13 +141,13 @@ struct gql_scanner
141
141
  enum gql_lexeme lexeme;
142
142
  };
143
143
 
144
- VALUE GQLParser;
145
- VALUE QLGParserToken;
146
- VALUE gql_eParserError;
144
+ extern VALUE GQLParser;
145
+ extern VALUE QLGParserToken;
146
+ extern VALUE gql_eParserError;
147
147
 
148
- const char *GQL_VALUE_KEYWORDS[3];
149
- const char *GQL_EXECUTION_KEYWORDS[5];
150
- const char *GQL_DEFINITION_KEYWORDS[12];
148
+ extern const char *GQL_VALUE_KEYWORDS[3];
149
+ extern const char *GQL_EXECUTION_KEYWORDS[5];
150
+ extern const char *GQL_DEFINITION_KEYWORDS[12];
151
151
 
152
152
  void gql_debug_print(const char *message);
153
153
  struct gql_scanner gql_new_scanner(VALUE source);
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails/generators/base'
4
+
5
+ module GraphQL
6
+ module Generators
7
+ class ChannelGenerator < Rails::Generators::Base # :nodoc:
8
+ include Rails::GraphQL::BaseGenerator
9
+
10
+ desc 'Add a new action cable channel that operates with GraphQL'
11
+
12
+ argument :name, type: :string, optional: true,
13
+ default: "GraphQLChannel",
14
+ desc: 'The name for the channel'
15
+
16
+ def create_channel_file
17
+ template 'channel.erb', "app/channels/#{channel_name.underscore}.rb"
18
+ end
19
+
20
+ private
21
+
22
+ def channel_name
23
+ @channel_name ||= options.fetch(:name, 'GraphQLChannel').classify
24
+ end
25
+ end
26
+ end
27
+ end
@@ -8,15 +8,20 @@ module GraphQL
8
8
  include Rails::GraphQL::BaseGenerator
9
9
 
10
10
  desc 'Add a new controller that operates with GraphQL'
11
- argument :name, type: :string, optional: true
11
+
12
+ argument :name, type: :string, optional: true,
13
+ default: "GraphQLController",
14
+ desc: 'The name for the controller'
12
15
 
13
16
  def create_controller_file
14
17
  template 'controller.erb', "app/controllers/#{controller_name.underscore}.rb"
15
18
  end
16
19
 
17
- def controller_name
18
- @controller_name ||= (options[:name].presence&.classify || 'GraphQL') + 'Controller'
19
- end
20
+ private
21
+
22
+ def controller_name
23
+ @controller_name ||= options.fetch(:name, 'GraphQLController').classify
24
+ end
20
25
  end
21
26
  end
22
27
  end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails/generators/base'
4
+
5
+ module GraphQL
6
+ module Generators
7
+ class InstallGenerator < Rails::Generators::Base # :nodoc:
8
+ include Rails::GraphQL::BaseGenerator
9
+
10
+ desc 'Add an initial setup to your application'
11
+
12
+ argument :schema, type: :string, optional: true,
13
+ default: "#{APP_MODULE_NAME}Schema",
14
+ desc: 'A name for the schema'
15
+
16
+ class_option :skip_routes, type: :boolean,
17
+ default: false,
18
+ desc: 'Add some initial routes'
19
+
20
+ class_option :skip_keeps, type: :boolean,
21
+ default: false,
22
+ desc: 'Skip .keep files'
23
+
24
+ def create_config_file
25
+ template 'config.rb', 'config/initializers/graphql.rb'
26
+ end
27
+
28
+ def create_schema
29
+ invoke 'graphql:schema'
30
+ end
31
+
32
+ def create_keep_files
33
+ return if options[:skip_keeps]
34
+
35
+ %w[
36
+ directives fields sources enums inputs interfaces object
37
+ scalars unions queries mutations subscriptions
38
+ ].each { |folder| create_file("#{options[:directory]}/#{folder}/.keep") }
39
+ end
40
+
41
+ def add_routes
42
+ return if options[:skip_routes]
43
+ route('get "/graphql/describe", to: "graphql/base#describe"')
44
+ route('get "/graphiql", to: "graphql/base#graphiql"')
45
+ route('post "/graphql", to: "graphql/base#execute"')
46
+ end
47
+ end
48
+ end
49
+ end
@@ -8,15 +8,20 @@ module GraphQL
8
8
  include Rails::GraphQL::BaseGenerator
9
9
 
10
10
  desc 'Add a new GraphQL schema'
11
- argument :name, type: :string, optional: true
11
+
12
+ argument :schema, type: :string, optional: true,
13
+ default: "#{APP_MODULE_NAME}Schema",
14
+ desc: 'A name for the schema'
12
15
 
13
16
  def create_schema_file
14
17
  template 'schema.erb', "#{options[:directory]}/#{schema_name.underscore}.rb"
15
18
  end
16
19
 
17
- def schema_name
18
- @schema_name ||= options[:name].presence || "#{app_module_name}Schema"
19
- end
20
+ private
21
+
22
+ def schema_name
23
+ @schema_name ||= options.fetch(:schema, "#{APP_MODULE_NAME}Schema")
24
+ end
20
25
  end
21
26
  end
22
27
  end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ <% module_namespacing do -%>
4
+ class <%= channel_name %> < ApplicationCable::Channel
5
+ include GraphQL::Channel
6
+ end
7
+ <% end -%>
@@ -0,0 +1,97 @@
1
+ # frozen_string_literal: true
2
+
3
+ Rails::GraphQL.configure do |config|
4
+ # This helps to keep track of when things were cached and registered. Cached
5
+ # objects with mismatching versions need to be upgraded or simply reloaded.
6
+ # An excellent way to use this is to set it to the commit hash. TypePap will
7
+ # always use only the first 8 characters for simplicity.
8
+ # config.version = nil
9
+
10
+ # The instance responsible for caching all the information generated by
11
+ # requests and all the other components. Manually setting this property
12
+ # means that the object in it complies with `ActiveSupport::Cache::Store`.
13
+ # This will map automatically to `Rails.cache` if kept as `nil`. This can
14
+ # also be set per Schema.
15
+ # config.cache = nil
16
+
17
+ # This is the prefix key of all the cache entries for the GraphQL cached
18
+ # things.
19
+ # config.cache_prefix = 'graphql/'
20
+
21
+ # This is very similar to `ActiveRecord` verbose logs, which simply show the
22
+ # path of the file that started a GraphQL request.
23
+ # config.verbose_logs = true
24
+
25
+ # The list of parameters to omit from the logger when running a GraphQL
26
+ # request. Those values are displayed better in the internal runtime logger
27
+ # controller.
28
+ # config.omit_parameters = %w[query operationName operation_name variables graphql]
29
+
30
+ # Identical to the one available on a Rails application, but exclusive for
31
+ # GraphQL operations. The list of parameters to display as filtered in the
32
+ # logs. When it is nil, it will use the same as the Rails application.
33
+ # config.filter_parameters = nil
34
+
35
+ # The suffix that is added automatically to all the Input type objects. This
36
+ # prevents situations like `PointInputInput`. If your inputs have a
37
+ # different suffix, change this value to it.
38
+ # config.auto_suffix_input_objects = 'Input'
39
+
40
+ # Introspection is enabled by default. It is recommended to only use
41
+ # introspection during development and tests, never in production.
42
+ # This can also be set per schema level.
43
+ config.enable_introspection = !Rails.env.production?
44
+
45
+ # Define the names of the schema/operations types. The single "_" is a
46
+ # suggestion. In an application that has a Subscription object, it will
47
+ # prevent the conflict. Plus, it is easy to spot that it is something
48
+ # internal. This can also be set per Schema.
49
+ # config.schema_type_names = {
50
+ # query: '_Query',
51
+ # mutation: '_Mutation',
52
+ # subscription: '_Subscription',
53
+ # }
54
+
55
+ # For performance purposes, this gem implements a
56
+ # {JsonCollector}[rdoc-ref:Rails::GraphQL::Collectors::JsonCollector].
57
+ # You can disable this option if you prefer to use the standard
58
+ # hash-to-string serialization provided by `ActiveSupport`.
59
+ # This can also be set per Schema.
60
+ # config.enable_string_collector = true
61
+
62
+ # Set what is de default expected output type of GraphQL requests. String
63
+ # combined with the previous setting has the best performance. On the
64
+ # console, it will automatically shift to Hash. This can also be set per
65
+ # Schema.
66
+ # config.default_response_format = :string
67
+
68
+ # Specifies if the results of operations should be encoded with
69
+ # +ActiveSupport::JSON#encode+ instead of the default +JSON#generate+.
70
+ # See also https://github.com/rails/rails/blob/master/activesupport/lib/active_support/json/encoding.rb
71
+ # config.encode_with_active_support = false
72
+
73
+ # Enable the ability of a callback to inject arguments dynamically into the
74
+ # calling method.
75
+ # config.callback_inject_arguments = true
76
+
77
+ # Enable the ability of a callback to inject named arguments dynamically
78
+ # into the calling method.
79
+ # config.callback_inject_named_arguments = true
80
+
81
+ # When importing fields from modules or other objects, a warning is
82
+ # displayed for any given element that was not able to be correctly
83
+ # imported. You can silence such warnings by changing this option.
84
+ # config.silence_import_warnings = false
85
+
86
+ # Enable the ability to define the description of any object, field, or
87
+ # argument using I18n. It is recommended for multi-language documentation.
88
+ config.enable_i18n_descriptions = true
89
+
90
+ # The method that should be used to parse literal input values when they are
91
+ # provided as Hash. `JSON.parse` only supports keys wrapped in quotes. You
92
+ # can use `Psych.method(:safe_load)` to support keys without quotes, which
93
+ # behaves closer to YAML. The received value is ensured to be wrapped in
94
+ # "{}". If that produces unexpected results, you can assign a proc and then
95
+ # parse the value in any other way.
96
+ # config.literal_input_parser = Psych.method(:safe_load)
97
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  <% module_namespacing do -%>
2
4
  class <%= controller_name %> < ApplicationController
3
5
  include GraphQL::Controller
@@ -1,6 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module GraphQL
2
- <% module_namespacing do -%>
3
- class <%= schema_name %> < Schema
4
+ <%- module_namespacing do -%>
5
+ class <%= schema_name %> < GraphQL::Schema
4
6
  end
5
- <% end -%>
7
+ <%- end -%>
6
8
  end
data/lib/gql_parser.so CHANGED
Binary file
@@ -15,22 +15,34 @@ module Rails
15
15
  self.field_type = Field::OutputField
16
16
  self.valid_field_types = Type::Object.valid_field_types
17
17
 
18
+ def self.i18n_scope
19
+ :query
20
+ end
21
+
18
22
  def self.inspect
19
23
  +"#<#{self.class.name} @fields=#{fields.inspect}>"
20
24
  end
21
25
  end
22
26
 
27
+ # = GraphQL Alternative Query Set
28
+ #
29
+ # Exact the same as a +FieldSet+
30
+ QuerySet = FieldSet
31
+
23
32
  # = GraphQL Alternative Mutation Set
24
33
  #
25
34
  # Same as a +FieldSet+ but for mutation fields
26
35
  MutationSet = Class.new(FieldSet)
27
36
  MutationSet.field_type = Field::MutationField
37
+ MutationSet.redefine_singleton_method(:i18n_scope) { :mutation }
38
+
28
39
 
29
40
  # = GraphQL Alternative Subscription Set
30
41
  #
31
42
  # Same as a +FieldSet+ but for subscription fields
32
43
  SubscriptionSet = Class.new(FieldSet)
33
44
  SubscriptionSet.field_type = Field::SubscriptionField
45
+ SubscriptionSet.redefine_singleton_method(:i18n_scope) { :subscription }
34
46
  end
35
47
  end
36
48
  end
@@ -15,9 +15,9 @@ module Rails
15
15
  self.abstract = true
16
16
 
17
17
  class << self
18
- delegate :gql_name, :to_sym, :desc, :argument, :ref_argument, :id_argument,
19
- :use, :internal?, :disabled?, :enabled?, :disable!, :enable!, :rename!,
20
- :authorize, :on, :description=, :description, to: :field
18
+ delegate :gql_name, :to_sym, :desc, :arguments, :argument, :ref_argument, :id_argument,
19
+ :use, :internal?, :disabled?, :enabled?, :disable!, :enable!, :rename!, :authorize,
20
+ :on, :description=, :description, to: :field
21
21
 
22
22
  # Returns the type of the field class
23
23
  def type_field_class
@@ -49,7 +49,7 @@ module Rails
49
49
  end
50
50
 
51
51
  # Create a new field for the class
52
- def define_field(field_name = nil, type = :any, **xargs, &blcok)
52
+ def define_field(field_name = nil, type = :any, **xargs, &block)
53
53
  field_name ||= anonymous? ? '_anonymous' : begin
54
54
  type_module = type_field_class.to_s.classify.pluralize
55
55
  user_name = name.split(+"#{type_module}::")[1]
@@ -58,12 +58,12 @@ module Rails
58
58
  end
59
59
 
60
60
  # Save the generated field ensuring the owner
61
- @field = field_class.new(field_name, type, **xargs, owner: self, &blcok)
61
+ @field = field_class.new(field_name, type, **xargs, owner: self, &block)
62
62
  end
63
63
 
64
64
  # Import the field from a given source
65
- def import_field(other_field, **xargs, &blcok)
66
- @field = other_field.to_proxy(**xargs, owner: self, &blcok)
65
+ def import_field(other_field, **xargs, &block)
66
+ @field = other_field.to_proxy(**xargs, owner: self, &block)
67
67
  end
68
68
 
69
69
  # Change the return type of the field
@@ -85,9 +85,14 @@ module Rails
85
85
  def field_class
86
86
  return @field.class if defined?(@field)
87
87
  list = Helpers::WithSchemaFields::TYPE_FIELD_CLASS
88
- GraphQL::Field.const_get(list[type_field_class])
88
+ GraphQL::Field.const_get(list[type_field_class], false)
89
89
  end
90
90
  end
91
91
  end
92
+
93
+ # = GraphQL Alternative Field
94
+ #
95
+ # Just an alias, since query fields are the same as output fields
96
+ Alternative.const_set(:Field, Alternative::Query)
92
97
  end
93
98
  end
@@ -10,7 +10,8 @@ module Rails
10
10
  self.abstract = true
11
11
 
12
12
  class << self
13
- delegate :scope, :trigger, to: :@field, allow_nil: true
13
+ delegate :scope, :trigger_for, :trigger, :unsubscribe_from, :unsubscribe,
14
+ to: :@field, allow_nil: true
14
15
  end
15
16
  end
16
17
  end
@@ -10,6 +10,10 @@ module Rails
10
10
  autoload :Mutation
11
11
  autoload :Subscription
12
12
 
13
+ autoload_at "#{__dir__}/alternative/query" do
14
+ autoload :Field
15
+ end
16
+
13
17
  autoload_at "#{__dir__}/alternative/field_set" do
14
18
  autoload :FieldSet
15
19
  autoload :MutationSet
@@ -43,19 +43,21 @@ module Rails
43
43
 
44
44
  def initialize(
45
45
  name,
46
- type,
46
+ type = nil,
47
47
  owner:,
48
48
  null: true,
49
49
  full: false,
50
50
  array: false,
51
51
  nullable: true,
52
52
  default: nil,
53
- desc: nil
53
+ desc: nil,
54
+ description: nil
54
55
  )
55
56
  @owner = owner
56
57
  @name = name.to_s.underscore.to_sym
57
58
  @gql_name = @name.to_s.camelize(:lower)
58
59
 
60
+ type = (name == :id ? :id : :string) if type.nil?
59
61
  if type.is_a?(Module) && type < GraphQL::Type
60
62
  @type_klass = type
61
63
  @type = type.name
@@ -69,7 +71,7 @@ module Rails
69
71
 
70
72
  @default = default
71
73
  @default = deserialize(@default) if @default.is_a?(::GQLParser::Token)
72
- self.description = desc
74
+ self.description = desc || description
73
75
  end
74
76
 
75
77
  def initialize_copy(*)
@@ -4,7 +4,7 @@ module Rails
4
4
  module GraphQL
5
5
  # = Rails GraphQL Callback
6
6
  #
7
- # An extra powerfull proc that can handle way more situations than the
7
+ # An extra powerful proc that can handle way more situations than the
8
8
  # original block caller
9
9
  class Callback
10
10
  EXCLUSIVE_ARGUMENT = :exclusive_callback
@@ -51,7 +51,7 @@ module Rails
51
51
  # This does the whole checking and preparation in order to really execute
52
52
  # the callback method
53
53
  def call(event, *args, _callback_context: nil, **xargs)
54
- return unless event.name === event_name && can_run?(event)
54
+ return unless event.event_name === event_name && can_run?(event)
55
55
 
56
56
  block.is_a?(Symbol) \
57
57
  ? call_symbol(event, *args, **xargs) \
@@ -66,10 +66,9 @@ module Rails
66
66
 
67
67
  # Get a described source location for the callback
68
68
  def source_location
69
- block.is_a?(Proc) ? block.source_location : [
70
- +"(symbolized-callback/#{target.inspect})",
71
- block,
72
- ]
69
+ block.is_a?(Proc) ? block.source_location : begin
70
+ [+"(symbolized-callback/#{target.inspect})", block]
71
+ end
73
72
  end
74
73
 
75
74
  # This basically allows the class to be passed as +&block+
@@ -84,7 +83,8 @@ module Rails
84
83
  # Find the proper owner of the symbol based callback
85
84
  def owner
86
85
  @owner ||= target.all_owners.find do |item|
87
- item.is_a?(Class) ? item.method_defined?(block) : item.respond_to?(block)
86
+ item.is_a?(Class) && item.included_modules.include?(Helpers::Instantiable) &&
87
+ item.method_defined?(block)
88
88
  end || target
89
89
  end
90
90
 
@@ -98,7 +98,8 @@ module Rails
98
98
  end
99
99
 
100
100
  # Call the callback block as a symbol
101
- # TODO: Maybe black calling non-public events
101
+ # TODO: Maybe block calling non-public events
102
+ # TODO: This is the only reason why directives needs an owner
102
103
  def call_symbol(event, *args, **xargs)
103
104
  event.on_instance(owner) do |instance|
104
105
  block = instance.method(@block)
@@ -110,6 +111,7 @@ module Rails
110
111
  # Call the callback block as a proc
111
112
  def call_proc(event, context = nil, *args, **xargs)
112
113
  args, xargs = collect_parameters(event, [args, xargs])
114
+ args << event unless inject_arguments? || (block.arity - 1) == args.size
113
115
  (context || event).instance_exec(*args, **xargs, &block)
114
116
  end
115
117
 
@@ -31,6 +31,11 @@ module Rails
31
31
  @data.is_a?(::Array) ? @data << value : @data[key.to_s] = value
32
32
  end
33
33
 
34
+ # Check if a given +key+ has already been added to the current data
35
+ def key?(key)
36
+ !@data.is_a?(::Array) && @data.key?(key)
37
+ end
38
+
34
39
  alias safe_add add
35
40
 
36
41
  # Serialize is a helper to call the correct method on types before add
@@ -45,13 +50,19 @@ module Rails
45
50
  @data = {}
46
51
  end
47
52
 
48
- # Append to the responsa data all the errors that happened during the
53
+ # Append to the response all the errors that happened during the
49
54
  # request process
50
55
  def append_errors(errors)
51
56
  return if errors.empty?
52
57
  @data['errors'] = errors.as_json
53
58
  end
54
59
 
60
+ # Append to the response anything added to the extensions
61
+ def append_extensions(extensions)
62
+ return if extensions.empty?
63
+ @data['extensions'] = extensions.as_json
64
+ end
65
+
55
66
  # Return the generated object
56
67
  def to_h
57
68
  @data
@@ -12,6 +12,9 @@ module Rails
12
12
  def initialize(request)
13
13
  @request = request
14
14
 
15
+ @current_keys = Set.new
16
+ @stack_keys = []
17
+
15
18
  @current_value = StringIO.new
16
19
  @stack_value = []
17
20
 
@@ -32,6 +35,7 @@ module Rails
32
35
  pop_size = array && !plain ? 2 : 1
33
36
  @current_value = @stack_value.pop(pop_size).first
34
37
  @current_array = @stack_array.pop(pop_size).first
38
+ @current_keys = @stack_keys.pop
35
39
  raise
36
40
  end
37
41
 
@@ -42,10 +46,17 @@ module Rails
42
46
  add('errors', errors.to_json)
43
47
  end
44
48
 
49
+ # Append to the response anything added to the extensions
50
+ def append_extensions(extensions)
51
+ return if extensions.empty?
52
+ add('extensions', extensions.to_json)
53
+ end
54
+
45
55
  # Add the given +value+ to the given +key+. Ensure to encode the value
46
56
  # before calling this function.
47
57
  def add(key, value)
48
58
  (@current_value << ',') if @current_value.pos > 0
59
+ @current_keys << key
49
60
 
50
61
  if @current_array
51
62
  @current_value << value
@@ -54,6 +65,11 @@ module Rails
54
65
  end
55
66
  end
56
67
 
68
+ # Check if the given +key+ has been added already
69
+ def key?(key)
70
+ @current_keys.include?(key)
71
+ end
72
+
57
73
  # Same as +add+ but this always encode the +value+ beforehand.
58
74
  def safe_add(key, value)
59
75
  add(key, value.nil? ? 'null' : value.to_json)
@@ -69,7 +85,9 @@ module Rails
69
85
  return unless @stack_array.last === :complex
70
86
  (@stack_value.last << ',') if @stack_value.last.pos > 0
71
87
  @stack_value.last << to_s
88
+
72
89
  @current_value = StringIO.new
90
+ @current_keys = Set.new
73
91
  end
74
92
 
75
93
  # Get the current result
@@ -90,6 +108,7 @@ module Rails
90
108
  def start_stack(as_array = false, plain_array = false)
91
109
  @stack_value << @current_value
92
110
  @stack_array << @current_array
111
+ @stack_keys << @current_keys
93
112
 
94
113
  if as_array && !plain_array
95
114
  @stack_value << StringIO.new
@@ -99,6 +118,7 @@ module Rails
99
118
 
100
119
  @current_value = StringIO.new
101
120
  @current_array = as_array
121
+ @current_keys = Set.new
102
122
  end
103
123
 
104
124
  # Finalize a stack and set the result on the given +key+.
@@ -111,6 +131,7 @@ module Rails
111
131
  result = to_s
112
132
  @current_value = @stack_value.pop
113
133
  @current_array = @stack_array.pop
134
+ @current_keys = @stack_keys.pop
114
135
  add(key, result)
115
136
  end
116
137
  end