graph_attack 1.1.0 → 1.2.0

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
- SHA1:
3
- metadata.gz: a15c0b11d8e25c73943da6bf70907df378deb42c
4
- data.tar.gz: 25e5f9f166d1bb010eee56c7e595b126fe05b748
2
+ SHA256:
3
+ metadata.gz: dd5c8edf29d269a309957b279c0690cb46f897ca4e02c8909cd80816b9ce76fb
4
+ data.tar.gz: ccf872288c199a97d55a36565998e04ca94edc982f1318bd66a67b70140aac9a
5
5
  SHA512:
6
- metadata.gz: ef5a10ecbc9cbe51553bce3936cdbee0eb3ff67bfee7b8f423bd91f2d9a7a012d6b615d2c961f16f1e5366f537ec60ba13ad5264d4141bfaca7a5fc3b25db6c4
7
- data.tar.gz: 542014545b679ea08d44c59ec07df312f31be870d02edb88d3d6bb559948ced10ea9d566b09a7aa1e5ccd028642b230b2ebf6097b337d40108a4fbec1cb9c364
6
+ metadata.gz: 5d7f367fa3125069280b021f6404a19e6a5bcba197ea3c3408b066eadb593e295f2cabcb7d3d4cda5ef0b2a806ac2055dc3943559257aea208dd077a62ff468c
7
+ data.tar.gz: 52adf301f34c476a6b6f97013175bc0036c588788d158d971ad553d62c86c54ac27ad1be83be6c99a120a0b90bf7b2e4da58455bd2988e9fd523ffa92956c203
data/.circleci/config.yml CHANGED
@@ -6,7 +6,7 @@ version: 2
6
6
  jobs:
7
7
  build:
8
8
  docker:
9
- - image: circleci/ruby:2.4.1-node-browsers
9
+ - image: circleci/ruby:2.7.3
10
10
  - image: redis
11
11
 
12
12
  working_directory: ~/repo
@@ -17,19 +17,16 @@ jobs:
17
17
  # Download and cache dependencies
18
18
  - restore_cache:
19
19
  keys:
20
- - v1-dependencies-{{ checksum "graph_attack.gemspec" }}
21
- # fallback to using the latest cache if no exact match is found
22
- - v1-dependencies-
20
+ - v2-dependencies-{{ checksum "graph_attack.gemspec" }}
21
+ - v2-dependencies-
23
22
 
24
- - run:
25
- name: install dependencies
26
- command: |
27
- bundle install --jobs=4 --retry=3 --path vendor/bundle
23
+ - run: gem install bundler:2.0.2
24
+ - run: bundle install --jobs=4 --retry=3 --path vendor/bundle
28
25
 
29
26
  - save_cache:
30
27
  paths:
31
28
  - ./vendor/bundle
32
- key: v1-dependencies-{{ checksum "graph_attack.gemspec" }}
29
+ key: v2-dependencies-{{ checksum "graph_attack.gemspec" }}
33
30
 
34
31
  # Run tests!
35
32
  - run:
@@ -0,0 +1,9 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: bundler
4
+ directory: "/"
5
+ schedule:
6
+ interval: daily
7
+ time: "04:00"
8
+ open-pull-requests-limit: 3
9
+ rebase-strategy: disabled
data/.rubocop.yml CHANGED
@@ -1,5 +1,9 @@
1
+ require:
2
+ - rubocop-rspec
3
+ - rubocop-rake
4
+
1
5
  AllCops:
2
- TargetRubyVersion: 2.3
6
+ TargetRubyVersion: 2.7
3
7
  DisplayCopNames: true
4
8
 
5
9
  # Do not sort gems in Gemfile, since we are grouping them by functionality.
@@ -22,20 +26,19 @@ Style/TrailingCommaInHashLiteral:
22
26
  Layout/MultilineMethodCallIndentation:
23
27
  EnforcedStyle: indented
24
28
 
29
+ Gemspec/RequiredRubyVersion:
30
+ Enabled: false
31
+
25
32
  # Limit method length (default is 10).
26
33
  Metrics/MethodLength:
27
34
  Max: 15
28
35
 
29
- # Do not require `# frozen_string_literal: true` at the top of every file.
30
- FrozenStringLiteralComment:
31
- Enabled: false
32
-
33
36
  # Allow ASCII comments (e.g "…").
34
37
  Style/AsciiComments:
35
38
  Enabled: false
36
39
 
37
40
  # Do not comment the class we create, since the name should be self explanatory.
38
- Documentation:
41
+ Style/Documentation:
39
42
  Enabled: false
40
43
 
41
44
  # Do not verify the length of the blocks in specs.
@@ -43,15 +46,119 @@ Metrics/BlockLength:
43
46
  Exclude:
44
47
  - spec/**/*
45
48
 
46
- # Allow indenting multiline chained operations.
47
- Layout/MultilineMethodCallIndentation:
48
- EnforcedStyle: indented
49
-
50
49
  # Prefer `== 0`, `< 0`, `> 0` to `zero?`, `negative?` or `positive?`,
51
50
  # since they don't exist before Ruby 2.3 or Rails 5 and can be ambiguous.
52
51
  Style/NumericPredicate:
53
52
  EnforcedStyle: comparison
54
53
 
55
- # Allow shorter argument names like `ip`.
56
- Naming/UncommunicativeMethodParamName:
57
- MinNameLength: 2
54
+ # Allow more expectations per example (default 1).
55
+ RSpec/MultipleExpectations:
56
+ Max: 5
57
+
58
+ # Allow more group nesting (default 3)
59
+ RSpec/NestedGroups:
60
+ Max: 5
61
+
62
+ # Allow longer examples (default 5)
63
+ RSpec/ExampleLength:
64
+ Max: 8
65
+
66
+ Layout/EmptyLinesAroundAttributeAccessor:
67
+ Enabled: true
68
+
69
+ Layout/SpaceAroundMethodCallOperator:
70
+ Enabled: true
71
+
72
+ Lint/DeprecatedOpenSSLConstant:
73
+ Enabled: true
74
+
75
+ Lint/MixedRegexpCaptureTypes:
76
+ Enabled: true
77
+
78
+ Lint/RaiseException:
79
+ Enabled: true
80
+
81
+ Lint/StructNewOverride:
82
+ Enabled: true
83
+
84
+ Style/ExponentialNotation:
85
+ Enabled: true
86
+
87
+ Style/HashEachMethods:
88
+ Enabled: true
89
+
90
+ Style/HashTransformKeys:
91
+ Enabled: true
92
+
93
+ Style/HashTransformValues:
94
+ Enabled: true
95
+
96
+ Style/RedundantRegexpCharacterClass:
97
+ Enabled: true
98
+
99
+ Style/RedundantRegexpEscape:
100
+ Enabled: true
101
+
102
+ Style/SlicingWithRange:
103
+ Enabled: true
104
+
105
+ Gemspec/DateAssignment: # (new in 1.10)
106
+ Enabled: true
107
+ Layout/SpaceBeforeBrackets: # (new in 1.7)
108
+ Enabled: true
109
+ Lint/AmbiguousAssignment: # (new in 1.7)
110
+ Enabled: true
111
+ Lint/DeprecatedConstants: # (new in 1.8)
112
+ Enabled: true
113
+ Lint/DuplicateBranch: # (new in 1.3)
114
+ Enabled: true
115
+ Lint/DuplicateRegexpCharacterClassElement: # (new in 1.1)
116
+ Enabled: true
117
+ Lint/EmptyBlock: # (new in 1.1)
118
+ Enabled: true
119
+ Lint/EmptyClass: # (new in 1.3)
120
+ Enabled: true
121
+ Lint/LambdaWithoutLiteralBlock: # (new in 1.8)
122
+ Enabled: true
123
+ Lint/NoReturnInBeginEndBlocks: # (new in 1.2)
124
+ Enabled: true
125
+ Lint/NumberedParameterAssignment: # (new in 1.9)
126
+ Enabled: true
127
+ Lint/OrAssignmentToConstant: # (new in 1.9)
128
+ Enabled: true
129
+ Lint/RedundantDirGlobSort: # (new in 1.8)
130
+ Enabled: true
131
+ Lint/SymbolConversion: # (new in 1.9)
132
+ Enabled: true
133
+ Lint/ToEnumArguments: # (new in 1.1)
134
+ Enabled: true
135
+ Lint/TripleQuotes: # (new in 1.9)
136
+ Enabled: true
137
+ Lint/UnexpectedBlockArity: # (new in 1.5)
138
+ Enabled: true
139
+ Lint/UnmodifiedReduceAccumulator: # (new in 1.1)
140
+ Enabled: true
141
+ Style/ArgumentsForwarding: # (new in 1.1)
142
+ Enabled: true
143
+ Style/CollectionCompact: # (new in 1.2)
144
+ Enabled: true
145
+ Style/DocumentDynamicEvalDefinition: # (new in 1.1)
146
+ Enabled: true
147
+ Style/EndlessMethod: # (new in 1.8)
148
+ Enabled: true
149
+ Style/HashConversion: # (new in 1.10)
150
+ Enabled: true
151
+ Style/HashExcept: # (new in 1.7)
152
+ Enabled: true
153
+ Style/IfWithBooleanLiteralBranches: # (new in 1.9)
154
+ Enabled: true
155
+ Style/NegatedIfElseCondition: # (new in 1.2)
156
+ Enabled: true
157
+ Style/NilLambda: # (new in 1.3)
158
+ Enabled: true
159
+ Style/RedundantArgument: # (new in 1.4)
160
+ Enabled: true
161
+ Style/StringChars: # (new in 1.12)
162
+ Enabled: true
163
+ Style/SwapValues: # (new in 1.1)
164
+ Enabled: true
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.7.3
data/.travis.yml CHANGED
@@ -1,5 +1,6 @@
1
1
  sudo: false
2
2
  language: ruby
3
3
  rvm:
4
- - 2.4.1
5
- before_install: gem install bundler -v 1.16.1
4
+ - 2.7.3
5
+ services:
6
+ - redis-server
data/CHANGELOG.md CHANGED
@@ -1,6 +1,13 @@
1
1
  unreleased
2
2
  ----------
3
3
 
4
+ v1.2.0
5
+ ------
6
+
7
+ Feature:
8
+ - New GraphAttack::RateLimit extension to be used in GraphQL::Ruby's class-based
9
+ syntax.
10
+
4
11
  v1.1.0
5
12
  ------
6
13
 
data/Gemfile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source 'https://rubygems.org'
2
4
 
3
5
  git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
data/README.md CHANGED
@@ -8,6 +8,19 @@ GraphQL analyser for blocking & throttling.
8
8
 
9
9
  This gem adds a method to limit access to your GraphQL fields by IP:
10
10
 
11
+ ```rb
12
+ class QueryType < GraphQL::Schema::Object
13
+ field :some_expensive_field, String, null: false do
14
+ extension(GraphAttack::RateLimit, threshold: 15, interval: 60)
15
+ end
16
+
17
+ # …
18
+ end
19
+ ```
20
+
21
+ <details>
22
+ <summary>If using GraphQL::Ruby's legacy schema definition</summary>
23
+
11
24
  ```rb
12
25
  QueryType = GraphQL::ObjectType.define do
13
26
  name 'Query'
@@ -20,6 +33,8 @@ QueryType = GraphQL::ObjectType.define do
20
33
  end
21
34
  ```
22
35
 
36
+ </details>
37
+
23
38
  This would allow only 15 calls per minute by the same IP.
24
39
 
25
40
  ## Requirements
@@ -42,6 +57,9 @@ And then execute:
42
57
  $ bundle
43
58
  ```
44
59
 
60
+ <details>
61
+ <summary>If using GraphQL::Ruby's legacy schema definition</summary>
62
+
45
63
  Add the query analyser to your schema:
46
64
 
47
65
  ```rb
@@ -52,8 +70,10 @@ ApplicationSchema = GraphQL::Schema.define do
52
70
  end
53
71
  ```
54
72
 
73
+ </details>
74
+
55
75
  Finally, make sure you add the current user's IP address as `ip:` to the
56
- GraphQL context:
76
+ GraphQL context. E.g.:
57
77
 
58
78
  ```rb
59
79
  class GraphqlController < ApplicationController
@@ -74,12 +94,28 @@ end
74
94
 
75
95
  Use a custom Redis client instead of the default:
76
96
 
97
+ ```rb
98
+ field :some_expensive_field, String, null: false do
99
+ extension(
100
+ GraphAttack::RateLimit,
101
+ threshold: 15,
102
+ interval: 60,
103
+ redis_client: Redis.new(url: "…"),
104
+ )
105
+ end
106
+ ```
107
+
108
+ <details>
109
+ <summary>If using GraphQL::Ruby's legacy schema definition</summary>
110
+
77
111
  ```rb
78
112
  query_analyzer GraphAttack::RateLimiter.new(
79
113
  redis_client: Redis.new(url: "…")
80
114
  )
81
115
  ```
82
116
 
117
+ </details>
118
+
83
119
  ## Development
84
120
 
85
121
  After checking out the repo, run `bin/setup` to install dependencies. Then, run
@@ -109,12 +145,12 @@ the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
109
145
 
110
146
  Everyone interacting in the GraphAttack project’s codebases, issue trackers,
111
147
  chat rooms and mailing lists is expected to follow the
112
- [code of conduct](https://github.com/sunny/graph_attack/blob/master/CODE_OF_CONDUCT.md).
148
+ [code of conduct](https://github.com/sunny/graph_attack/blob/main/CODE_OF_CONDUCT.md).
113
149
 
114
150
  ## License
115
151
 
116
152
  This project is licensed under the MIT License - see the
117
- [LICENSE.md](https://github.com/sunny/graph_attack/blob/master/LICENSE.md)
153
+ [LICENSE.md](https://github.com/sunny/graph_attack/blob/main/LICENSE.md)
118
154
  file for details.
119
155
 
120
156
  ## Authors
data/Rakefile CHANGED
@@ -1,12 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Bundler
2
4
  require 'bundler/gem_tasks'
3
- require 'rspec/core/rake_task'
4
5
 
5
- # Rspec
6
+ # RSpec
6
7
  require 'rspec/core/rake_task'
7
8
  RSpec::Core::RakeTask.new(:spec)
8
9
 
9
- task default: :spec
10
10
  # Rubocop
11
11
  require 'rubocop/rake_task'
12
12
  RuboCop::RakeTask.new(:rubocop)
data/bin/console CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'bundler/setup'
4
5
  require 'graph_attack'
data/bin/rake ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'rake' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
10
+
11
+ require 'pathname'
12
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile',
13
+ Pathname.new(__FILE__).realpath)
14
+
15
+ bundle_binstub = File.expand_path('bundle', __dir__)
16
+
17
+ if File.file?(bundle_binstub)
18
+ if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19
+ load(bundle_binstub)
20
+ else
21
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22
+ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23
+ end
24
+ end
25
+
26
+ require 'rubygems'
27
+ require 'bundler/setup'
28
+
29
+ load Gem.bin_path('rake', 'rake')
data/bin/rubocop ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'rubocop' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
10
+
11
+ require 'pathname'
12
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile',
13
+ Pathname.new(__FILE__).realpath)
14
+
15
+ bundle_binstub = File.expand_path('bundle', __dir__)
16
+
17
+ if File.file?(bundle_binstub)
18
+ if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19
+ load(bundle_binstub)
20
+ else
21
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22
+ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23
+ end
24
+ end
25
+
26
+ require 'rubygems'
27
+ require 'bundler/setup'
28
+
29
+ load Gem.bin_path('rubocop', 'rubocop')
data/graph_attack.gemspec CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  lib = File.expand_path('lib', __dir__)
2
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
5
  require 'graph_attack/version'
@@ -18,6 +20,7 @@ Gem::Specification.new do |spec|
18
20
  spec.bindir = 'exe'
19
21
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
22
  spec.require_paths = ['lib']
23
+ spec.required_ruby_version = ['>= 2.5.7', '< 2.8']
21
24
 
22
25
  # This gem is an analyser for the GraphQL ruby gem.
23
26
  spec.add_dependency 'graphql', '>= 1.7.9'
@@ -26,10 +29,10 @@ Gem::Specification.new do |spec|
26
29
  spec.add_dependency 'ratelimit', '>= 1.0.3'
27
30
 
28
31
  # Loads local dependencies.
29
- spec.add_development_dependency 'bundler', '~> 1.15'
32
+ spec.add_development_dependency 'bundler', '~> 2.0'
30
33
 
31
34
  # Development tasks runner.
32
- spec.add_development_dependency 'rake', '~> 10.0'
35
+ spec.add_development_dependency 'rake', '~> 13.0'
33
36
 
34
37
  # Testing framework.
35
38
  spec.add_development_dependency 'rspec', '~> 3.0'
@@ -38,5 +41,11 @@ Gem::Specification.new do |spec|
38
41
  spec.add_development_dependency 'rspec_junit_formatter', '~> 0.3'
39
42
 
40
43
  # Ruby code linter.
41
- spec.add_development_dependency 'rubocop', '~> 0.55'
44
+ spec.add_development_dependency 'rubocop', '~> 1.1'
45
+
46
+ # RSpec extension for RuboCop.
47
+ spec.add_development_dependency 'rubocop-rspec', '~> 2.2'
48
+
49
+ # Rake extension for RuboCop
50
+ spec.add_development_dependency 'rubocop-rake'
42
51
  end
data/lib/graph_attack.rb CHANGED
@@ -1,7 +1,17 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'graphql'
2
4
  require 'ratelimit'
5
+
3
6
  require 'graphql/tracing'
4
7
 
5
8
  require 'graph_attack/version'
9
+
10
+ # Class-based schema
11
+ require 'graph_attack/rate_limit'
12
+ require 'graph_attack/error'
13
+ require 'graph_attack/rate_limited'
14
+
15
+ # Legacy schema
6
16
  require 'graph_attack/rate_limiter'
7
17
  require 'graph_attack/metadata'
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GraphAttack
4
+ class Error < StandardError; end
5
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Add custom field metadata
2
4
  GraphQL::Field.accepts_definitions(
3
5
  rate_limit: GraphQL::Define.assign_metadata_key(:rate_limit),
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GraphAttack
4
+ class RateLimit < GraphQL::Schema::FieldExtension
5
+ def resolve(object:, arguments:, **_rest)
6
+ ip = object.context[:ip]
7
+ raise GraphAttack::Error, 'Missing :ip value on the GraphQL context' unless ip
8
+
9
+ return RateLimited.new('Query rate limit exceeded') if calls_exceeded_on_query?(ip)
10
+
11
+ yield(object, arguments)
12
+ end
13
+
14
+ private
15
+
16
+ def key
17
+ "graphql-query-#{field.name}"
18
+ end
19
+
20
+ def calls_exceeded_on_query?(ip)
21
+ rate_limit = Ratelimit.new(ip, redis: redis_client)
22
+ rate_limit.add(key)
23
+ rate_limit.exceeded?(
24
+ key,
25
+ threshold: threshold,
26
+ interval: interval,
27
+ )
28
+ end
29
+
30
+ def threshold
31
+ options[:threshold] ||
32
+ raise(
33
+ GraphAttack::Error,
34
+ 'Missing "threshold:" option on the GraphAttack::RateLimit extension',
35
+ )
36
+ end
37
+
38
+ def interval
39
+ options[:interval] ||
40
+ raise(
41
+ GraphAttack::Error,
42
+ 'Missing "interval:" option on the GraphAttack::RateLimit extension',
43
+ )
44
+ end
45
+
46
+ def redis_client
47
+ options[:redis_client] || Redis.current
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GraphAttack
4
+ class RateLimited < GraphQL::AnalysisError; end
5
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module GraphAttack
2
4
  # Query analyser you can add to your GraphQL schema to limit calls by IP.
3
5
  #
@@ -7,6 +9,7 @@ module GraphAttack
7
9
  #
8
10
  class RateLimiter
9
11
  class Error < StandardError; end
12
+
10
13
  class RateLimited < GraphQL::AnalysisError; end
11
14
 
12
15
  def initialize(redis_client: Redis.new)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module GraphAttack
2
- VERSION = '1.1.0'.freeze
4
+ VERSION = '1.2.0'
3
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: graph_attack
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Fanny Cheung
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2019-02-18 00:00:00.000000000 Z
12
+ date: 2021-07-27 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: graphql
@@ -45,28 +45,28 @@ dependencies:
45
45
  requirements:
46
46
  - - "~>"
47
47
  - !ruby/object:Gem::Version
48
- version: '1.15'
48
+ version: '2.0'
49
49
  type: :development
50
50
  prerelease: false
51
51
  version_requirements: !ruby/object:Gem::Requirement
52
52
  requirements:
53
53
  - - "~>"
54
54
  - !ruby/object:Gem::Version
55
- version: '1.15'
55
+ version: '2.0'
56
56
  - !ruby/object:Gem::Dependency
57
57
  name: rake
58
58
  requirement: !ruby/object:Gem::Requirement
59
59
  requirements:
60
60
  - - "~>"
61
61
  - !ruby/object:Gem::Version
62
- version: '10.0'
62
+ version: '13.0'
63
63
  type: :development
64
64
  prerelease: false
65
65
  version_requirements: !ruby/object:Gem::Requirement
66
66
  requirements:
67
67
  - - "~>"
68
68
  - !ruby/object:Gem::Version
69
- version: '10.0'
69
+ version: '13.0'
70
70
  - !ruby/object:Gem::Dependency
71
71
  name: rspec
72
72
  requirement: !ruby/object:Gem::Requirement
@@ -101,14 +101,42 @@ dependencies:
101
101
  requirements:
102
102
  - - "~>"
103
103
  - !ruby/object:Gem::Version
104
- version: '0.55'
104
+ version: '1.1'
105
105
  type: :development
106
106
  prerelease: false
107
107
  version_requirements: !ruby/object:Gem::Requirement
108
108
  requirements:
109
109
  - - "~>"
110
110
  - !ruby/object:Gem::Version
111
- version: '0.55'
111
+ version: '1.1'
112
+ - !ruby/object:Gem::Dependency
113
+ name: rubocop-rspec
114
+ requirement: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - "~>"
117
+ - !ruby/object:Gem::Version
118
+ version: '2.2'
119
+ type: :development
120
+ prerelease: false
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - "~>"
124
+ - !ruby/object:Gem::Version
125
+ version: '2.2'
126
+ - !ruby/object:Gem::Dependency
127
+ name: rubocop-rake
128
+ requirement: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - ">="
131
+ - !ruby/object:Gem::Version
132
+ version: '0'
133
+ type: :development
134
+ prerelease: false
135
+ version_requirements: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - ">="
138
+ - !ruby/object:Gem::Version
139
+ version: '0'
112
140
  description: GraphQL analyser for blocking & throttling
113
141
  email:
114
142
  - fanny@ynote.hk
@@ -118,9 +146,11 @@ extensions: []
118
146
  extra_rdoc_files: []
119
147
  files:
120
148
  - ".circleci/config.yml"
149
+ - ".github/dependabot.yml"
121
150
  - ".gitignore"
122
151
  - ".rspec"
123
152
  - ".rubocop.yml"
153
+ - ".ruby-version"
124
154
  - ".travis.yml"
125
155
  - CHANGELOG.md
126
156
  - CODE_OF_CONDUCT.md
@@ -129,10 +159,15 @@ files:
129
159
  - README.md
130
160
  - Rakefile
131
161
  - bin/console
162
+ - bin/rake
163
+ - bin/rubocop
132
164
  - bin/setup
133
165
  - graph_attack.gemspec
134
166
  - lib/graph_attack.rb
167
+ - lib/graph_attack/error.rb
135
168
  - lib/graph_attack/metadata.rb
169
+ - lib/graph_attack/rate_limit.rb
170
+ - lib/graph_attack/rate_limited.rb
136
171
  - lib/graph_attack/rate_limiter.rb
137
172
  - lib/graph_attack/version.rb
138
173
  homepage: https://github.com/sunny/graph_attack
@@ -146,15 +181,17 @@ required_ruby_version: !ruby/object:Gem::Requirement
146
181
  requirements:
147
182
  - - ">="
148
183
  - !ruby/object:Gem::Version
149
- version: '0'
184
+ version: 2.5.7
185
+ - - "<"
186
+ - !ruby/object:Gem::Version
187
+ version: '2.8'
150
188
  required_rubygems_version: !ruby/object:Gem::Requirement
151
189
  requirements:
152
190
  - - ">="
153
191
  - !ruby/object:Gem::Version
154
192
  version: '0'
155
193
  requirements: []
156
- rubyforge_project:
157
- rubygems_version: 2.6.11
194
+ rubygems_version: 3.1.6
158
195
  signing_key:
159
196
  specification_version: 4
160
197
  summary: GraphQL analyser for blocking & throttling