graphql-persisted_queries 1.4.0 → 1.5.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/rspec.yml +1 -0
- data/.gitignore +2 -0
- data/CHANGELOG.md +8 -0
- data/README.md +0 -10
- data/gemfiles/graphql_2_0_0.gemfile +5 -0
- data/lib/graphql/persisted_queries/compiled_queries/interpreter_patch.rb +162 -0
- data/lib/graphql/persisted_queries/version.rb +1 -1
- data/lib/graphql/persisted_queries.rb +11 -4
- metadata +8 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 78784d32983df6d9d75af398dcf87f1239e37dce760eb99b73c3ebcf5856ee8c
|
4
|
+
data.tar.gz: d2e0a437767dfa2a148654b32ebfe7669167273fcf123de9b9834ac733cc3f03
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b070e30dea650ae02e6164440cd1b7b1a73796b98db7e691c8ff10fce9b5eb9351daebcbf68f2d2d3e7d2ccdf8bb6503f00eae2060a674be66d1229811e3f375
|
7
|
+
data.tar.gz: cb4f0137249ab7414857af926833de0d8060a8fc77eb7f29fb2853dfcb22f85382ed8341169a7b0015c21fd52429b7e735c67e1923545ba69d44441166c217e6
|
data/.github/workflows/rspec.yml
CHANGED
data/.gitignore
CHANGED
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,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
|
@@ -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
|
-
|
46
|
-
GraphQL::
|
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
|
+
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-
|
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.
|
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: []
|