graphql-persisted_queries 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: c766b357d35d1bda4dfba34a5a633260a0dfe3593189f1d60b35d5973b5c18a4
4
+ data.tar.gz: 6182e3cdb5ce2ed6194b7ee4eef87ad2c3194299904bd1ecaf29fc5179c1358e
5
+ SHA512:
6
+ metadata.gz: 6ee805aae51f2ecf5c055eb5c3d02b20873369a990498f0b2e75348ab62cf8192945b9716d87c616772e2c07b000fd8b73a238e45124cd7e849e3d3041e41cf6
7
+ data.tar.gz: 49b7cbe475f09c7f4ec6e4b11a1dbcb3d86a03fcd6d63ef4acf977e59aff6c6e223e858d24f96f6895d8ccee9495f0ffbd623a28e48eec89ccd895fa284cd4d0
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+ Gemfile.lock
data/.rubocop.yml ADDED
@@ -0,0 +1,26 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.6
3
+ Include:
4
+ - 'lib/**/*.rb'
5
+ - 'spec/**/*.rb'
6
+ Exclude:
7
+ - 'bin/**/*'
8
+ - 'vendor/**/*'
9
+ - 'gemfiles/**/*.gemfile'
10
+ - 'gemfiles/vendor/**/*'
11
+ - 'Rakefile'
12
+ - 'Gemfile'
13
+ - '*.gemspec'
14
+
15
+ Style/StringLiterals:
16
+ EnforcedStyle: double_quotes
17
+
18
+ Metrics/LineLength:
19
+ Max: 100
20
+
21
+ Metrics/BlockLength:
22
+ Exclude:
23
+ - 'spec/**/*.rb'
24
+
25
+ Style/NumericLiterals:
26
+ Enabled: false
data/.travis.yml ADDED
@@ -0,0 +1,23 @@
1
+ language: ruby
2
+ cache: bundler
3
+
4
+ sudo: false
5
+
6
+ rvm:
7
+ - 2.3
8
+ - 2.4
9
+ - 2.5
10
+ - 2.6
11
+ - ruby-head
12
+
13
+ gemfile:
14
+ - gemfiles/graphql_1_8.gemfile
15
+ - gemfiles/graphql_1_9.gemfile
16
+ - gemfiles/graphql_master.gemfile
17
+
18
+
19
+ notifications:
20
+ email: false
21
+
22
+ matrix:
23
+ fast_finish: true
data/CHANGELOG.md ADDED
@@ -0,0 +1,9 @@
1
+ # Change log
2
+
3
+ ## master
4
+
5
+ ## 0.1.0 (2019-10-21)
6
+
7
+ - Initial version ([@DmitryTsepelev][])
8
+
9
+ [@DmitryTsepelev]: https://github.com/DmitryTsepelev
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in graphql-persisted_queries.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2019 DmitryTsepelev
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,100 @@
1
+ # GraphQL::PersistedQueries [![Build Status](https://travis-ci.org/DmitryTsepelev/graphql-ruby-persisted_queries.svg?branch=master)](https://travis-ci.org/DmitryTsepelev/graphql-ruby-persisted_queries)
2
+
3
+
4
+ `GraphQL::PersistedQueries` is the implementation of [persisted queries](https://github.com/apollographql/apollo-link-persisted-queries) for [graphql-ruby](https://github.com/rmosolgo/graphql-ruby). With this plugin your backend will cache all the queries, while frontend will send the full query only when it's not found at the backend storage.
5
+
6
+ - 🗑**Heavy query parameter will be omitted in most of cases** – network requests will become less heavy
7
+ - 🤝**Clients share cached queries** – it's enough to miss cache only once for each unique query
8
+ - 🎅**Works for clients without persisted query support**
9
+
10
+
11
+ <p align="center">
12
+ <a href="https://evilmartians.com/?utm_source=graphql-ruby-persisted_queries">
13
+ <img src="https://evilmartians.com/badges/sponsored-by-evil-martians.svg" alt="Sponsored by Evil Martians" width="236" height="54">
14
+ </a>
15
+ </p>
16
+
17
+ ## Installation
18
+
19
+ 1. Add the gem to your Gemfile `gem 'graphql-persisted_queries'`
20
+
21
+ 2. Install and configure [apollo-link-persisted-queries](https://github.com/apollographql/apollo-link-persisted-queries):
22
+
23
+ ```js
24
+ import { createPersistedQueryLink } from "apollo-link-persisted-queries";
25
+ import { createHttpLink } from "apollo-link-http";
26
+ import { InMemoryCache } from "apollo-cache-inmemory";
27
+ import ApolloClient from "apollo-client";
28
+
29
+
30
+ // use this with Apollo Client
31
+ const link = createPersistedQueryLink().concat(createHttpLink({ uri: "/graphql" }));
32
+ const client = new ApolloClient({
33
+ cache: new InMemoryCache(),
34
+ link: link,
35
+ });
36
+ ```
37
+
38
+ 3. Add plugin to the schema:
39
+
40
+ ```ruby
41
+ class GraphqlSchema < GraphQL::Schema
42
+ use GraphQL::PersistedQueries
43
+ end
44
+ ```
45
+
46
+ 4. Pass `:extensions` argument to all calls of `GraphqlSchema#execute` (start with `GraphqlController` and `GraphqlChannel`)
47
+
48
+ ```ruby
49
+ GraphqlSchema.execute(
50
+ params[:query],
51
+ variables: ensure_hash(params[:variables]),
52
+ context: {},
53
+ operation_name: params[:operationName],
54
+ extensions: ensure_hash(params[:extensions])
55
+ )
56
+ ```
57
+
58
+ 5. Run the app! 🔥
59
+
60
+ ## Alternative stores
61
+
62
+ All the queries are stored in memory by default, but you can easily switch to _redis_:
63
+
64
+ ```ruby
65
+ class GraphqlSchema < GraphQL::Schema
66
+ use GraphQL::PersistedQueries, store: :redis, redis_url: ENV["MY_REDIS_URL"]
67
+ end
68
+ ```
69
+
70
+ If you have `ENV["REDIS_URL"]` configured – you don't need to pass it explicitly. Also, you can pass `:redis_host`, `:redis_port` and `:redis_db_name` to build the URL from scratch or configure Redis client as you want and pass it as the `:client` option.
71
+
72
+ ## Alternative hash functions
73
+
74
+ [apollo-link-persisted-queries](https://github.com/apollographql/apollo-link-persisted-queries) uses _SHA256_ by default so this gem uses it as a default too, but if you want to override it – you can use `:hash_generator` option:
75
+
76
+ ```ruby
77
+ class GraphqlSchema < GraphQL::Schema
78
+ use GraphQL::PersistedQueries, hash_generator: :md5
79
+ end
80
+ ```
81
+
82
+ If string or symbol is passed – the gem would try to find the class in the `Digest` namespace. Altenatively, you can pass a lambda, e.g.:
83
+
84
+ ```ruby
85
+ class GraphqlSchema < GraphQL::Schema
86
+ use GraphQL::PersistedQueries, hash_generator: proc { |_value| "super_safe_hash!!!" }
87
+ end
88
+ ```
89
+
90
+ ## GET requests and HTTP cache
91
+
92
+ Using `GET` requests for persisted queries allows you to enable HTTP caching (e.g., turn on CDN). In order to make it work you should change the way link is initialized on front-end side (`createPersistedQueryLink({ useGETForHashedQueries: true })`) and register a new route `get "/graphql", to: "graphql#execute"`.
93
+
94
+ ## Contributing
95
+
96
+ Bug reports and pull requests are welcome on GitHub at https://github.com/DmitryTsepelev/graphql-persisted_queries.
97
+
98
+ ## License
99
+
100
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+ require "rubocop/rake_task"
4
+
5
+ RSpec::Core::RakeTask.new(:spec)
6
+ RuboCop::RakeTask.new
7
+
8
+ task default: [:rubocop, :spec]
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "graphql/persisted_queries"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,5 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem "graphql", "~> 1.8"
4
+
5
+ gemspec path: "../"
@@ -0,0 +1,5 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem "graphql", "~> 1.9"
4
+
5
+ gemspec path: "../"
@@ -0,0 +1,5 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem "graphql", github: "rmosolgo/graphql-ruby"
4
+
5
+ gemspec path: ".."
@@ -0,0 +1,31 @@
1
+ lib = File.expand_path("lib", __dir__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require "graphql/persisted_queries/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "graphql-persisted_queries"
7
+ spec.version = GraphQL::PersistedQueries::VERSION
8
+ spec.authors = ["DmitryTsepelev"]
9
+ spec.email = ["dmitry.a.tsepelev@gmail.com"]
10
+
11
+ spec.summary = "Persisted queries for graphql-ruby"
12
+ spec.description = "Persisted queries for graphql-ruby"
13
+ spec.homepage = "https://github.com/DmitryTsepelev/graphql-ruby-persisted_queries"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
17
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ end
19
+ spec.bindir = "exe"
20
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
+ spec.require_paths = ["lib"]
22
+
23
+ spec.required_ruby_version = ">= 2.3"
24
+
25
+ spec.add_dependency "graphql", ">= 1.8"
26
+
27
+ spec.add_development_dependency "rspec", "~> 3.9"
28
+ spec.add_development_dependency "rake", ">= 10.0"
29
+ spec.add_development_dependency "rubocop", "0.75"
30
+ spec.add_development_dependency "redis"
31
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "graphql/persisted_queries/schema_patch"
4
+ require "graphql/persisted_queries/store_adapters"
5
+ require "graphql/persisted_queries/version"
6
+
7
+ module GraphQL
8
+ # Plugin definition
9
+ module PersistedQueries
10
+ def self.use(schema_defn, store: :memory, hash_generator: :sha256, **options)
11
+ schema_defn.target.singleton_class.prepend(SchemaPatch)
12
+ schema_defn.target.hash_generator = hash_generator
13
+ schema_defn.target.configure_persisted_query_store(store, options)
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "digest"
4
+
5
+ module GraphQL
6
+ module PersistedQueries
7
+ # Builds hash generator
8
+ class HashGeneratorBuilder
9
+ def initialize(generator)
10
+ @generator = generator
11
+ end
12
+
13
+ def build
14
+ if @generator.is_a?(Proc)
15
+ build_from_proc
16
+ else
17
+ build_from_name
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ def build_from_proc
24
+ if @generator.arity != 1
25
+ raise ArgumentError, "proc passed to :hash_generator should have exactly one argument"
26
+ end
27
+
28
+ @generator
29
+ end
30
+
31
+ def build_from_name
32
+ upcased_name = @generator.to_s.upcase
33
+ digest_class = Digest.const_get(upcased_name)
34
+ proc { |value| digest_class.hexdigest(value) }
35
+ rescue LoadError => e
36
+ raise NameError, "digest class for :#{@generator} haven't been found", e.backtrace
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GraphQL
4
+ module PersistedQueries
5
+ # Fetches or stores query string in the storage
6
+ class Resolver
7
+ # Raised when persisted query is not found in the storage
8
+ class NotFound < StandardError
9
+ def message
10
+ "PersistedQueryNotFound"
11
+ end
12
+ end
13
+
14
+ # Raised when provided hash is not matched with query
15
+ class WrongHash < StandardError
16
+ def message
17
+ "Wrong hash was passed"
18
+ end
19
+ end
20
+
21
+ def initialize(extensions, store, hash_generator_proc)
22
+ @extensions = extensions
23
+ @store = store
24
+ @hash_generator_proc = hash_generator_proc
25
+ end
26
+
27
+ def resolve(query_str)
28
+ return query_str if hash.nil?
29
+
30
+ if query_str
31
+ persist_query(query_str)
32
+ else
33
+ query_str = @store.fetch_query(hash)
34
+ raise NotFound if query_str.nil?
35
+ end
36
+
37
+ query_str
38
+ end
39
+
40
+ private
41
+
42
+ def persist_query(query_str)
43
+ raise WrongHash if @hash_generator_proc.call(query_str) != hash
44
+
45
+ @store.save_query(hash, query_str)
46
+ end
47
+
48
+ def hash
49
+ @hash ||= @extensions.dig("persistedQuery", "sha256Hash")
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "graphql/persisted_queries/hash_generator_builder"
4
+ require "graphql/persisted_queries/resolver"
5
+
6
+ module GraphQL
7
+ module PersistedQueries
8
+ # Patches GraphQL::Schema to support persisted queries
9
+ module SchemaPatch
10
+ attr_reader :persisted_query_store, :hash_generator_proc
11
+
12
+ def configure_persisted_query_store(store, options)
13
+ @persisted_query_store = StoreAdapters.build(store, options)
14
+ end
15
+
16
+ def hash_generator=(hash_generator)
17
+ @hash_generator_proc = HashGeneratorBuilder.new(hash_generator).build
18
+ end
19
+
20
+ def execute(query_str = nil, **kwargs)
21
+ if (extensions = kwargs.delete(:extensions))
22
+ resolver = Resolver.new(extensions, persisted_query_store, hash_generator_proc)
23
+ query_str = resolver.resolve(query_str)
24
+ end
25
+
26
+ super
27
+ rescue Resolver::NotFound, Resolver::WrongHash => e
28
+ { errors: [{ message: e.message }] }
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "graphql/persisted_queries/store_adapters/base_store_adapter"
4
+ require "graphql/persisted_queries/store_adapters/memory_store_adapter"
5
+ require "graphql/persisted_queries/store_adapters/redis_store_adapter"
6
+
7
+ module GraphQL
8
+ module PersistedQueries
9
+ # Contains factory methods for store adapters
10
+ module StoreAdapters
11
+ def self.build(adapter, options = nil)
12
+ if adapter.is_a?(StoreAdapters::BaseStoreAdapter)
13
+ adapter
14
+ else
15
+ build_by_name(adapter, options)
16
+ end
17
+ end
18
+
19
+ def self.build_by_name(name, options)
20
+ camelized_adapter = name.to_s.split("_").map(&:capitalize).join
21
+ adapter_class_name = "#{camelized_adapter}StoreAdapter"
22
+ StoreAdapters.const_get(adapter_class_name).new(options || {})
23
+ rescue NameError => e
24
+ raise e.class, "Persisted query store adapter for :#{name} haven't been found", e.backtrace
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GraphQL
4
+ module PersistedQueries
5
+ module StoreAdapters
6
+ # Base class for all store adapters
7
+ class BaseStoreAdapter
8
+ def initialize(_options); end
9
+
10
+ def fetch_query(_hash)
11
+ raise NotImplementedError
12
+ end
13
+
14
+ def save_query(_hash, _query)
15
+ raise NotImplementedError
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GraphQL
4
+ module PersistedQueries
5
+ module StoreAdapters
6
+ # Memory adapter for storing persisted queries
7
+ class MemoryStoreAdapter < BaseStoreAdapter
8
+ def initialize(_options)
9
+ @storage = {}
10
+ end
11
+
12
+ def fetch_query(hash)
13
+ @storage[hash]
14
+ end
15
+
16
+ def save_query(hash, query)
17
+ @storage[hash] = query
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GraphQL
4
+ module PersistedQueries
5
+ module StoreAdapters
6
+ # Redis adapter for storing persisted queries
7
+ class RedisStoreAdapter < BaseStoreAdapter
8
+ attr_reader :storage
9
+
10
+ def initialize(client: nil, **options)
11
+ require "redis"
12
+
13
+ if client && options.any?
14
+ raise ArgumentError, "client cannot be passed along with redis_url, redis_host" \
15
+ ", redis_port or redis_db_name options"
16
+ end
17
+
18
+ @storage = client || configure_redis_client(options)
19
+ rescue LoadError => e
20
+ msg = "Could not load the 'redis' gem, please add it to your gemfile or " \
21
+ "configure a different adapter, e.g. use GraphQL::PersistedQueries, store: :memory"
22
+ raise e.class, msg, e.backtrace
23
+ end
24
+
25
+ def fetch_query(hash)
26
+ storage.get(key_for(hash))
27
+ end
28
+
29
+ def save_query(hash, query)
30
+ storage.set(key_for(hash), query)
31
+ end
32
+
33
+ private
34
+
35
+ def key_for(hash)
36
+ "persisted-query-#{hash}"
37
+ end
38
+
39
+ # rubocop:disable Metrics/LineLength
40
+ def configure_redis_client(redis_url: nil, redis_host: nil, redis_port: nil, redis_db_name: nil)
41
+ if redis_url && (redis_host || redis_port || redis_db_name)
42
+ raise ArgumentError, "redis_url cannot be passed along with redis_host, redis_port " \
43
+ "or redis_db_name options"
44
+ end
45
+
46
+ redis_url ||= build_redis_url(
47
+ redis_host: redis_host,
48
+ redis_port: redis_port,
49
+ redis_db_name: redis_db_name
50
+ )
51
+
52
+ Redis.new(url: redis_url)
53
+ end
54
+ # rubocop:enable Metrics/LineLength
55
+
56
+ DEFAULT_REDIS_DB = "0"
57
+
58
+ def build_redis_url(redis_host: nil, redis_port: nil, redis_db_name: nil)
59
+ redis_db_name ||= DEFAULT_REDIS_DB
60
+ redis_base_url = ENV["REDIS_URL"] || "redis://#{redis_host}:#{redis_port}"
61
+ URI.join(redis_base_url, redis_db_name).to_s
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GraphQL
4
+ module PersistedQueries
5
+ VERSION = "0.1.0"
6
+ end
7
+ end
metadata ADDED
@@ -0,0 +1,136 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: graphql-persisted_queries
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - DmitryTsepelev
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2019-10-21 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: graphql
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '1.8'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '1.8'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '3.9'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '3.9'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '10.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '10.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rubocop
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '='
60
+ - !ruby/object:Gem::Version
61
+ version: '0.75'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '='
67
+ - !ruby/object:Gem::Version
68
+ version: '0.75'
69
+ - !ruby/object:Gem::Dependency
70
+ name: redis
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: Persisted queries for graphql-ruby
84
+ email:
85
+ - dmitry.a.tsepelev@gmail.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - ".gitignore"
91
+ - ".rubocop.yml"
92
+ - ".travis.yml"
93
+ - CHANGELOG.md
94
+ - Gemfile
95
+ - LICENSE.txt
96
+ - README.md
97
+ - Rakefile
98
+ - bin/console
99
+ - bin/setup
100
+ - gemfiles/graphql_1_8.gemfile
101
+ - gemfiles/graphql_1_9.gemfile
102
+ - gemfiles/graphql_master.gemfile
103
+ - graphql-persisted_queries.gemspec
104
+ - lib/graphql/persisted_queries.rb
105
+ - lib/graphql/persisted_queries/hash_generator_builder.rb
106
+ - lib/graphql/persisted_queries/resolver.rb
107
+ - lib/graphql/persisted_queries/schema_patch.rb
108
+ - lib/graphql/persisted_queries/store_adapters.rb
109
+ - lib/graphql/persisted_queries/store_adapters/base_store_adapter.rb
110
+ - lib/graphql/persisted_queries/store_adapters/memory_store_adapter.rb
111
+ - lib/graphql/persisted_queries/store_adapters/redis_store_adapter.rb
112
+ - lib/graphql/persisted_queries/version.rb
113
+ homepage: https://github.com/DmitryTsepelev/graphql-ruby-persisted_queries
114
+ licenses:
115
+ - MIT
116
+ metadata: {}
117
+ post_install_message:
118
+ rdoc_options: []
119
+ require_paths:
120
+ - lib
121
+ required_ruby_version: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - ">="
124
+ - !ruby/object:Gem::Version
125
+ version: '2.3'
126
+ required_rubygems_version: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - ">="
129
+ - !ruby/object:Gem::Version
130
+ version: '0'
131
+ requirements: []
132
+ rubygems_version: 3.0.3
133
+ signing_key:
134
+ specification_version: 4
135
+ summary: Persisted queries for graphql-ruby
136
+ test_files: []