graphql-persisted_queries 1.4.0 → 1.5.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8558536fae24e519c7b69751dea1ccf0f3cd2abec21f2811fd7bcf91418d88fe
4
- data.tar.gz: 2b0e05c819b934c6e660bba97151c2c58b38f11aa0396d19d2631eee4285ab71
3
+ metadata.gz: 78784d32983df6d9d75af398dcf87f1239e37dce760eb99b73c3ebcf5856ee8c
4
+ data.tar.gz: d2e0a437767dfa2a148654b32ebfe7669167273fcf123de9b9834ac733cc3f03
5
5
  SHA512:
6
- metadata.gz: 58b48712a5cc3a8330c6c7c6796c86478668f9a1ea18ac6161e7a86f2cbee04106725bf12dbf1365165f79d9e29a64d801e71b221469c88138e4c749424c0206
7
- data.tar.gz: a276474166be60c6b80625d9f6f3ab1501fc8927e3e70fcefe817f4083a3e6dc46fa0ee7535349a9d71b3f9f5cfcafaf411ef7690859bf16d6da472af9f245c8
6
+ metadata.gz: b070e30dea650ae02e6164440cd1b7b1a73796b98db7e691c8ff10fce9b5eb9351daebcbf68f2d2d3e7d2ccdf8bb6503f00eae2060a674be66d1229811e3f375
7
+ data.tar.gz: cb4f0137249ab7414857af926833de0d8060a8fc77eb7f29fb2853dfcb22f85382ed8341169a7b0015c21fd52429b7e735c67e1923545ba69d44441166c217e6
@@ -25,6 +25,7 @@ jobs:
25
25
  "gemfiles/graphql_1_12_0.gemfile",
26
26
  "gemfiles/graphql_1_12_4.gemfile",
27
27
  "gemfiles/graphql_1_13_7.gemfile",
28
+ "gemfiles/graphql_2_0_0.gemfile",
28
29
  "gemfiles/graphql_master.gemfile"
29
30
  ]
30
31
 
data/.gitignore CHANGED
@@ -7,3 +7,5 @@
7
7
  /spec/reports/
8
8
  /tmp/
9
9
  Gemfile.lock
10
+
11
+ .ruby-version
data/CHANGELOG.md CHANGED
@@ -2,6 +2,14 @@
2
2
 
3
3
  ## master
4
4
 
5
+ ## 1.5.1 (2022-09-28)
6
+
7
+ - [PR#56](https://github.com/DmitryTsepelev/graphql-ruby-persisted_queries/pull/56) Support graphql-ruby 2.0.14 ([@DmitryTsepelev][])
8
+
9
+ ## 1.5.0 (2022-02-10)
10
+
11
+ - [PR#53](https://github.com/DmitryTsepelev/graphql-ruby-persisted_queries/pull/53) Support graphql-ruby 2.0.0 ([@DmitryTsepelev][])
12
+
5
13
  ## 1.4.0 (2022-01-28)
6
14
 
7
15
  - [PR#52](https://github.com/DmitryTsepelev/graphql-ruby-persisted_queries/pull/52) Drop Ruby 2.5 support, add Ruby 3.0 ([@DmitryTsepelev][])
data/README.md CHANGED
@@ -38,16 +38,6 @@ class GraphqlSchema < GraphQL::Schema
38
38
  end
39
39
  ```
40
40
 
41
- **Heads up!** If you've already switched to interpreter mode and and AST analyzers—make sure AST plugin is added _before_ `GraphQL::PersistedQueries`:
42
-
43
- ```ruby
44
- class GraphqlSchema < GraphQL::Schema
45
- use GraphQL::Execution::Interpreter
46
- use GraphQL::Analysis::AST
47
- use GraphQL::PersistedQueries
48
- end
49
- ```
50
-
51
41
  Pass `:extensions` argument as part of a `context` to all calls of `GraphqlSchema#execute`, usually it happens in `GraphqlController`, `GraphqlChannel` and tests:
52
42
 
53
43
  ```ruby
@@ -0,0 +1,5 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem "graphql", "~> 2.0.0"
4
+
5
+ gemspec path: "../"
@@ -0,0 +1,162 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GraphQL
4
+ module PersistedQueries
5
+ module CompiledQueries
6
+ # Patches GraphQL::Execution::Multiplex to support compiled queries
7
+ # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Layout/IndentationWidth
8
+ # rubocop:disable Metrics/PerceivedComplexity, Metrics/ModuleLength, Metrics/LineLength
9
+ # rubocop:disable Metrics/BlockLength, Style/BracesAroundHashParameters, Style/CommentAnnotation
10
+ # rubocop:disable Naming/RescuedExceptionsVariableName, Layout/SpaceInsideHashLiteralBraces
11
+ # rubocop:disable Lint/ShadowingOuterLocalVariable, Style/BlockDelimiters, Metrics/MethodLength
12
+ # rubocop:disable Style/Next, Layout/ElseAlignment, Layout/EndAlignment, Lint/RescueException
13
+ module InterpreterPatch
14
+ # This method is fully copied from the gem because I didn't find a way to patch it. In future we will
15
+ # need to keep it in sync and migrate the monkey patch to newer versions of the file.
16
+ def run_all(schema, query_options, context: {}, max_complexity: schema.max_complexity)
17
+ queries = query_options.map do |opts|
18
+ case opts
19
+ when Hash
20
+ GraphQL::Query.new(schema, nil, **opts)
21
+ when GraphQL::Query
22
+ opts
23
+ else
24
+ raise "Expected Hash or GraphQL::Query, not #{opts.class} (#{opts.inspect})"
25
+ end
26
+ end
27
+
28
+ multiplex = Execution::Multiplex.new(schema: schema, queries: queries, context: context, max_complexity: max_complexity)
29
+ multiplex.trace("execute_multiplex", { multiplex: multiplex }) do
30
+ schema = multiplex.schema
31
+ queries = multiplex.queries
32
+ query_instrumenters = schema.instrumenters[:query]
33
+ multiplex_instrumenters = schema.instrumenters[:multiplex]
34
+
35
+ # First, run multiplex instrumentation, then query instrumentation for each query
36
+ call_hooks(multiplex_instrumenters, multiplex, :before_multiplex, :after_multiplex) do
37
+ each_query_call_hooks(query_instrumenters, queries) do
38
+ schema = multiplex.schema
39
+ multiplex_analyzers = schema.multiplex_analyzers
40
+ queries = multiplex.queries
41
+ if multiplex.max_complexity
42
+ multiplex_analyzers += [GraphQL::Analysis::AST::MaxQueryComplexity]
43
+ end
44
+
45
+ schema.analysis_engine.analyze_multiplex(multiplex, multiplex_analyzers)
46
+ begin
47
+ # Since this is basically the batching context,
48
+ # share it for a whole multiplex
49
+ multiplex.context[:interpreter_instance] ||= multiplex.schema.query_execution_strategy.new
50
+ # Do as much eager evaluation of the query as possible
51
+ results = []
52
+ queries.each_with_index do |query, idx|
53
+ multiplex.dataloader.append_job {
54
+ operation = query.selected_operation
55
+ result =
56
+ # MONKEY PATCH START
57
+ if query.persisted_query_not_found?
58
+ query.context.errors.clear
59
+ query.context.errors << GraphQL::ExecutionError.new("PersistedQueryNotFound")
60
+ singleton_class::NO_OPERATION
61
+ # MONKEY PATCH END
62
+ elsif operation.nil? || !query.valid? || query.context.errors.any?
63
+ singleton_class::NO_OPERATION
64
+ else
65
+ begin
66
+ # Although queries in a multiplex _share_ an Interpreter instance,
67
+ # they also have another item of state, which is private to that query
68
+ # in particular, assign it here:
69
+ runtime = GraphQL::Execution::Interpreter::Runtime.new(query: query)
70
+ query.context.namespace(:interpreter)[:runtime] = runtime
71
+
72
+ query.trace("execute_query", {query: query}) do
73
+ runtime.run_eager
74
+ end
75
+ rescue GraphQL::ExecutionError => err
76
+ query.context.errors << err
77
+ singleton_class::NO_OPERATION
78
+ end
79
+ end
80
+ results[idx] = result
81
+ }
82
+ end
83
+
84
+ multiplex.dataloader.run
85
+
86
+ # Then, work through lazy results in a breadth-first way
87
+ multiplex.dataloader.append_job {
88
+ tracer = multiplex
89
+ query = multiplex.queries.length == 1 ? multiplex.queries[0] : nil
90
+ queries = multiplex ? multiplex.queries : [query]
91
+ final_values = queries.map do |query|
92
+ runtime = query.context.namespace(:interpreter)[:runtime]
93
+ # it might not be present if the query has an error
94
+ runtime ? runtime.final_result : nil
95
+ end
96
+ final_values.compact!
97
+ tracer.trace("execute_query_lazy", {multiplex: multiplex, query: query}) do
98
+ GraphQL::Execution::Interpreter::Resolve.resolve_all(final_values, multiplex.dataloader)
99
+ end
100
+ queries.each do |query|
101
+ runtime = query.context.namespace(:interpreter)[:runtime]
102
+ if runtime
103
+ runtime.delete_interpreter_context(:current_path)
104
+ runtime.delete_interpreter_context(:current_field)
105
+ runtime.delete_interpreter_context(:current_object)
106
+ runtime.delete_interpreter_context(:current_arguments)
107
+ end
108
+ end
109
+ }
110
+ multiplex.dataloader.run
111
+
112
+ # Then, find all errors and assign the result to the query object
113
+ results.each_with_index do |data_result, idx|
114
+ query = queries[idx]
115
+ # Assign the result so that it can be accessed in instrumentation
116
+ query.result_values = if data_result.equal?(singleton_class::NO_OPERATION)
117
+ if !query.valid? || query.context.errors.any?
118
+ # A bit weird, but `Query#static_errors` _includes_ `query.context.errors`
119
+ { "errors" => query.static_errors.map(&:to_h) }
120
+ else
121
+ data_result
122
+ end
123
+ else
124
+ result = {
125
+ "data" => query.context.namespace(:interpreter)[:runtime].final_result
126
+ }
127
+
128
+ if query.context.errors.any?
129
+ error_result = query.context.errors.map(&:to_h)
130
+ result["errors"] = error_result
131
+ end
132
+
133
+ result
134
+ end
135
+ if query.context.namespace?(:__query_result_extensions__)
136
+ query.result_values["extensions"] = query.context.namespace(:__query_result_extensions__)
137
+ end
138
+ # Get the Query::Result, not the Hash
139
+ results[idx] = query.result
140
+ end
141
+
142
+ results
143
+ rescue Exception
144
+ # TODO rescue at a higher level so it will catch errors in analysis, too
145
+ # Assign values here so that the query's `@executed` becomes true
146
+ queries.map { |q| q.result_values ||= {} }
147
+ raise
148
+ end
149
+ end
150
+ end
151
+ end
152
+ end
153
+ end
154
+ end
155
+ # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Layout/IndentationWidth
156
+ # rubocop:enable Metrics/PerceivedComplexity, Metrics/ModuleLength, Metrics/LineLength
157
+ # rubocop:enable Metrics/BlockLength, Style/BracesAroundHashParameters, Style/CommentAnnotation
158
+ # rubocop:enable Naming/RescuedExceptionsVariableName, Layout/SpaceInsideHashLiteralBraces
159
+ # rubocop:enable Lint/ShadowingOuterLocalVariable, Style/BlockDelimiters, Metrics/MethodLength
160
+ # rubocop:enable Style/Next, Layout/ElseAlignment, Layout/EndAlignment, Lint/RescueException
161
+ end
162
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module GraphQL
4
4
  module PersistedQueries
5
- VERSION = "1.4.0"
5
+ VERSION = "1.5.1"
6
6
  end
7
7
  end
@@ -10,6 +10,7 @@ require "graphql/persisted_queries/builder_helpers"
10
10
 
11
11
  require "graphql/persisted_queries/compiled_queries/resolver"
12
12
  require "graphql/persisted_queries/compiled_queries/multiplex_patch"
13
+ require "graphql/persisted_queries/compiled_queries/interpreter_patch"
13
14
  require "graphql/persisted_queries/compiled_queries/query_patch"
14
15
 
15
16
  module GraphQL
@@ -37,14 +38,20 @@ module GraphQL
37
38
  end
38
39
  # rubocop:enable Metrics/MethodLength
39
40
 
40
- def self.configure_compiled_queries
41
+ def self.configure_compiled_queries # rubocop:disable Metrics/MethodLength
41
42
  if Gem::Dependency.new("graphql", "< 1.12.0").match?("graphql", GraphQL::VERSION)
42
43
  raise ArgumentError, "compiled_queries are not supported for graphql-ruby < 1.12.0"
43
44
  end
44
45
 
45
- GraphQL::Execution::Multiplex.singleton_class.prepend(
46
- GraphQL::PersistedQueries::CompiledQueries::MultiplexPatch
47
- )
46
+ if Gem::Dependency.new("graphql", ">= 2.0.14").match?("graphql", GraphQL::VERSION)
47
+ GraphQL::Execution::Interpreter.singleton_class.prepend(
48
+ GraphQL::PersistedQueries::CompiledQueries::InterpreterPatch
49
+ )
50
+ else
51
+ GraphQL::Execution::Multiplex.singleton_class.prepend(
52
+ GraphQL::PersistedQueries::CompiledQueries::MultiplexPatch
53
+ )
54
+ end
48
55
 
49
56
  GraphQL::Query.prepend(GraphQL::PersistedQueries::CompiledQueries::QueryPatch)
50
57
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: graphql-persisted_queries
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.0
4
+ version: 1.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - DmitryTsepelev
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-01-28 00:00:00.000000000 Z
11
+ date: 2022-09-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: graphql
@@ -141,6 +141,7 @@ files:
141
141
  - gemfiles/graphql_1_12_0.gemfile
142
142
  - gemfiles/graphql_1_12_4.gemfile
143
143
  - gemfiles/graphql_1_13_7.gemfile
144
+ - gemfiles/graphql_2_0_0.gemfile
144
145
  - gemfiles/graphql_master.gemfile
145
146
  - graphql-persisted_queries.gemspec
146
147
  - lib/graphql/persisted_queries.rb
@@ -148,6 +149,7 @@ files:
148
149
  - lib/graphql/persisted_queries/analyzers/http_method_ast_analyzer.rb
149
150
  - lib/graphql/persisted_queries/analyzers/http_method_validator.rb
150
151
  - lib/graphql/persisted_queries/builder_helpers.rb
152
+ - lib/graphql/persisted_queries/compiled_queries/interpreter_patch.rb
151
153
  - lib/graphql/persisted_queries/compiled_queries/multiplex_patch.rb
152
154
  - lib/graphql/persisted_queries/compiled_queries/query_patch.rb
153
155
  - lib/graphql/persisted_queries/compiled_queries/resolver.rb
@@ -173,7 +175,7 @@ homepage: https://github.com/DmitryTsepelev/graphql-ruby-persisted_queries
173
175
  licenses:
174
176
  - MIT
175
177
  metadata: {}
176
- post_install_message:
178
+ post_install_message:
177
179
  rdoc_options: []
178
180
  require_paths:
179
181
  - lib
@@ -188,8 +190,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
188
190
  - !ruby/object:Gem::Version
189
191
  version: '0'
190
192
  requirements: []
191
- rubygems_version: 3.0.3.1
192
- signing_key:
193
+ rubygems_version: 3.3.7
194
+ signing_key:
193
195
  specification_version: 4
194
196
  summary: Persisted queries for graphql-ruby
195
197
  test_files: []