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 +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: []
|