mangadex 5.3.1.3 → 5.3.3.2

Sign up to get free protection for your applications and to get access to all the features.
data/lib/mangadex/auth.rb CHANGED
@@ -3,16 +3,20 @@ module Mangadex
3
3
  class Auth
4
4
  extend T::Sig
5
5
 
6
- sig { params(username: String, password: String).returns(T.any(T::Boolean, Mangadex::Api::Response)) }
7
- def self.login(username, password)
6
+ sig { params(username: T.nilable(String), email: T.nilable(String), password: String).returns(T.nilable(Mangadex::Api::User)) }
7
+ def self.login(username: nil, email: nil, password: nil)
8
+ args = { password: password }
9
+ args.merge!(email: email) if email
10
+ args.merge!(username: username) if username
11
+
8
12
  response = Mangadex::Internal::Request.post(
9
13
  '/auth/login',
10
- payload: {
11
- username: username,
12
- password: password,
13
- },
14
+ payload: Mangadex::Internal::Definition.validate(args, {
15
+ username: { accepts: String },
16
+ email: { accepts: String },
17
+ password: { accepts: String, required: true },
18
+ }),
14
19
  )
15
- return response if response.is_a?(Mangadex::Api::Response) && response.errored?
16
20
 
17
21
  session = response.dig('token', 'session')
18
22
  refresh = response.dig('token', 'refresh')
@@ -20,13 +24,19 @@ module Mangadex
20
24
  mangadex_user = Mangadex::Internal::Request.get('/user/me', headers: { Authorization: session })
21
25
 
22
26
  user = Mangadex::Api::User.new(
23
- mangadex_user.data.id,
27
+ mangadex_user_id: mangadex_user.data.id,
24
28
  session: session,
25
29
  refresh: refresh,
26
30
  data: mangadex_user.data,
27
31
  )
28
- Mangadex::Api::Context.user = user
29
- !user.session_expired?
32
+ return if user.session_expired?
33
+
34
+ Mangadex.context.user = user
35
+
36
+ user.persist
37
+ user
38
+ rescue Errors::UnauthorizedError => error
39
+ raise Errors::AuthenticationError.new(error.response)
30
40
  end
31
41
 
32
42
  sig { returns(Hash) }
@@ -41,20 +51,39 @@ module Mangadex
41
51
 
42
52
  sig { returns(T.any(T::Boolean, Mangadex::Api::Response)) }
43
53
  def self.logout
44
- return true if Mangadex::Api::Context.user.nil?
54
+ return true if Mangadex.context.user.nil?
45
55
 
46
56
  response = Mangadex::Internal::Request.post(
47
57
  '/auth/logout',
48
58
  )
49
59
  return reponse if response.is_a?(Mangadex::Api::Response) && response.errored?
50
60
 
51
- Mangadex::Api::Context.user = nil
61
+ clear_user
62
+ true
63
+ rescue Mangadex::Errors::UnauthorizedError
64
+ clear_user
52
65
  true
53
66
  end
54
67
 
55
68
  sig { returns(T::Boolean) }
56
69
  def self.refresh_token
57
- !(Mangadex::Api::Context.user&.refresh!).nil?
70
+ !(Mangadex.context.user&.refresh!).nil?
71
+ end
72
+
73
+ private
74
+
75
+ sig { void }
76
+ def self.clear_user
77
+ return if Mangadex.context.user.nil?
78
+
79
+ if Mangadex.context.user.respond_to?(:session=)
80
+ Mangadex.context.user.session = nil
81
+ end
82
+ if Mangadex.context.user.respond_to?(:refresh=)
83
+ Mangadex.context.user.refresh = nil
84
+ end
85
+ Mangadex.storage.clear(Mangadex.context.user.mangadex_user_id)
86
+ Mangadex.context.user = nil
58
87
  end
59
88
  end
60
89
  end
@@ -4,7 +4,24 @@ require_relative 'mangadex_object'
4
4
 
5
5
  module Mangadex
6
6
  class Author < MangadexObject
7
- has_attributes :name, :image_url, :biography, :version, :created_at, :updated_at
7
+ has_attributes \
8
+ :name,
9
+ :image_url,
10
+ :biography,
11
+ :twitter,
12
+ :pixiv,
13
+ :melon_book,
14
+ :fan_box,
15
+ :booth,
16
+ :nico_video,
17
+ :skeb,
18
+ :fantia,
19
+ :tumblr,
20
+ :youtube,
21
+ :website,
22
+ :version,
23
+ :created_at,
24
+ :updated_at
8
25
 
9
26
  # List all authors.
10
27
  # Path: +GET /author+
@@ -49,6 +66,8 @@ module Mangadex
49
66
  # @return [Mangadex::Api::Response] with a entity of author
50
67
  sig { params(id: String, args: T::Api::Arguments).returns(Mangadex::Api::Response[Author]) }
51
68
  def self.get(id, **args)
69
+ Mangadex::Internal::Definition.must(id)
70
+
52
71
  Mangadex::Internal::Request.get(
53
72
  format('/author/%{id}', id: id),
54
73
  Mangadex::Internal::Definition.validate(args, {
@@ -64,6 +83,8 @@ module Mangadex
64
83
  # @return [Mangadex::Api::Response] with a entity of author
65
84
  sig { params(id: String, args: T::Api::Arguments).returns(Mangadex::Api::Response[Author]) }
66
85
  def self.update(id, **args)
86
+ Mangadex::Internal::Definition.must(id)
87
+
67
88
  Mangadex::Internal::Request.put(
68
89
  format('/author/%{id}', id: id),
69
90
  payload: Mangadex::Internal::Definition.validate(args, {
@@ -81,6 +102,8 @@ module Mangadex
81
102
  # @return [Hash]
82
103
  sig { params(id: String).returns(Hash) }
83
104
  def self.delete(id)
105
+ Mangadex::Internal::Definition.must(id)
106
+
84
107
  Mangadex::Internal::Request.delete(
85
108
  format('/author/%{id}', id: id)
86
109
  )
@@ -90,6 +113,10 @@ module Mangadex
90
113
  [:name]
91
114
  end
92
115
 
116
+ class << self
117
+ alias_method :view, :get
118
+ end
119
+
93
120
  # Indicates if this is an artist
94
121
  #
95
122
  # @return [Boolean] whether this is an artist or not.
@@ -26,11 +26,14 @@ module Mangadex
26
26
  Mangadex::Internal::Request.get(
27
27
  '/chapter',
28
28
  Mangadex::Internal::Definition.chapter_list(args),
29
+ content_rating: true,
29
30
  )
30
31
  end
31
32
 
32
33
  sig { params(id: String, args: T::Api::Arguments).returns(Mangadex::Api::Response[Chapter]) }
33
34
  def self.get(id, **args)
35
+ Mangadex::Internal::Definition.must(id)
36
+
34
37
  Mangadex::Internal::Request.get(
35
38
  '/chapter/%{id}' % {id: id},
36
39
  Mangadex::Internal::Definition.validate(args, {
@@ -41,6 +44,8 @@ module Mangadex
41
44
 
42
45
  sig { params(id: String, args: T::Api::Arguments).returns(Mangadex::Api::Response[Chapter]) }
43
46
  def self.update(id, **args)
47
+ Mangadex::Internal::Definition.must(id)
48
+
44
49
  Mangadex::Internal::Request.put(
45
50
  '/chapter/%{id}' % {id: id},
46
51
  payload: Mangadex::Internal::Definition.validate(args, {
@@ -56,11 +61,17 @@ module Mangadex
56
61
 
57
62
  sig { params(id: String).returns(Hash) }
58
63
  def self.delete(id)
64
+ Mangadex::Internal::Definition.must(id)
65
+
59
66
  Mangadex::Internal::Request.delete(
60
67
  '/chapter/%{id}' % {id: id},
61
68
  )
62
69
  end
63
70
 
71
+ class << self
72
+ alias_method :view, :get
73
+ end
74
+
64
75
  sig { returns(String) }
65
76
  def title
66
77
  attributes&.title.presence || chapter.presence && "Chapter #{chapter}" || "N/A"
@@ -28,6 +28,11 @@ module Mangadex
28
28
  SCORES.keys.map { |key| ContentRating.new(key) }.select { |record| record <= content_rating }.sort
29
29
  end
30
30
 
31
+ sig { params(content_ratings: T::Array[T.any(T::Api::Text, T::Api::ContentRating)]).returns(T::Array[ContentRating]) }
32
+ def self.parse(content_ratings)
33
+ content_ratings.map { |content_rating| ContentRating.new(content_rating) }.uniq
34
+ end
35
+
31
36
  sig { params(value: T.any(T::Api::Text, T::Api::ContentRating)).void }
32
37
  def initialize(value)
33
38
  @value = ensure_value!(value.to_s)
@@ -64,7 +69,7 @@ module Mangadex
64
69
 
65
70
  private
66
71
 
67
- sig { params(value: T.any(T::Api::Text, T::Api::ContentRating)).void }
72
+ sig { params(value: T.any(T::Api::Text, T::Api::ContentRating)).returns(T.any(T::Api::Text, T::Api::ContentRating)) }
68
73
  def ensure_value!(value)
69
74
  return value if value.is_a?(ContentRating)
70
75
  return value if VALUES.include?(value)
@@ -47,6 +47,8 @@ module Mangadex
47
47
 
48
48
  sig { params(id: String, args: T::Api::Arguments).returns(Mangadex::Api::Response[CoverArt]) }
49
49
  def self.get(id, **args)
50
+ Mangadex::Internal::Definition.must(id)
51
+
50
52
  Mangadex::Internal::Request.get(
51
53
  '/cover/%{id}' % {id: id},
52
54
  Mangadex::Internal::Definition.validate(args, {
@@ -57,6 +59,8 @@ module Mangadex
57
59
 
58
60
  sig { params(id: String, args: T::Api::Arguments).returns(Mangadex::Api::Response[CoverArt]) }
59
61
  def self.edit(id, **args)
62
+ Mangadex::Internal::Definition.must(id)
63
+
60
64
  Mangadex::Internal::Request.put(
61
65
  '/cover/%{id}' % {id: id},
62
66
  Mangadex::Internal::Definition.validate(args, {
@@ -69,11 +73,18 @@ module Mangadex
69
73
 
70
74
  sig { params(id: String).returns(Hash) }
71
75
  def self.delete(id)
76
+ Mangadex::Internal::Definition.must(id)
77
+
72
78
  Mangadex::Internal::Request.delete(
73
79
  '/cover/%{id}' % {id: id},
74
80
  )
75
81
  end
76
82
 
83
+ class << self
84
+ alias_method :view, :get
85
+ alias_method :update, :edit
86
+ end
87
+
77
88
  sig { params(size: T::Api::Text).returns(T.nilable(String)) }
78
89
  def image_url(size: :small)
79
90
  return unless manga.present?
@@ -24,6 +24,8 @@ module Mangadex
24
24
 
25
25
  sig { params(id: String).returns(Mangadex::Api::Response[CustomList]) }
26
26
  def self.get(id)
27
+ Mangadex::Internal::Definition.must(id)
28
+
27
29
  Mangadex::Internal::Request.get(
28
30
  '/list/%{id}' % {id: id},
29
31
  )
@@ -31,6 +33,8 @@ module Mangadex
31
33
 
32
34
  sig { params(id: String, args: T::Api::Arguments).returns(Mangadex::Api::Response[CustomList]) }
33
35
  def self.update(id, **args)
36
+ Mangadex::Internal::Definition.must(id)
37
+
34
38
  Mangadex::Internal::Request.put(
35
39
  '/list/%{id}' % {id: id},
36
40
  payload: Mangadex::Internal::Definition.validate(args, {
@@ -44,6 +48,8 @@ module Mangadex
44
48
 
45
49
  sig { params(id: String).returns(T::Boolean) }
46
50
  def self.delete(id)
51
+ Mangadex::Internal::Definition.must(id)
52
+
47
53
  Mangadex::Internal::Request.delete(
48
54
  '/list/%{id}' % {id: id},
49
55
  )
@@ -51,14 +57,19 @@ module Mangadex
51
57
 
52
58
  sig { params(id: String, args: T::Api::Arguments).returns(Mangadex::Api::Response[Chapter]) }
53
59
  def self.feed(id, **args)
60
+ Mangadex::Internal::Definition.must(id)
61
+
54
62
  Mangadex::Internal::Request.get(
55
63
  '/list/%{id}/feed' % {id: id},
56
64
  Mangadex::Internal::Definition.chapter_list(args),
65
+ content_rating: true,
57
66
  )
58
67
  end
59
68
 
60
69
  sig { params(id: String, list_id: String).returns(T::Boolean) }
61
70
  def self.add_manga(id, list_id:)
71
+ Mangadex::Internal::Definition.must(id)
72
+
62
73
  response = Mangadex::Internal::Request.post(
63
74
  '/manga/%{id}/list/%{list_id}' % {id: id, list_id: list_id},
64
75
  )
@@ -71,6 +82,8 @@ module Mangadex
71
82
 
72
83
  sig { params(id: String, list_id: String).returns(T::Boolean) }
73
84
  def self.remove_manga(id, list_id:)
85
+ Mangadex::Internal::Definition.must(id)
86
+
74
87
  response = Mangadex::Internal::Request.delete(
75
88
  '/manga/%{id}/list/%{list_id}' % {id: id, list_id: list_id},
76
89
  )
@@ -94,6 +107,8 @@ module Mangadex
94
107
 
95
108
  sig { params(user_id: String, args: T::Api::Arguments).returns(Mangadex::Api::Response[CustomList]) }
96
109
  def self.user_list(user_id, **args)
110
+ Mangadex::Internal::Definition.must(user_id)
111
+
97
112
  Mangadex::Internal::Request.get(
98
113
  '/user/%{id}/list' % {id: user_id},
99
114
  Mangadex::Internal::Definition.validate(args, {
@@ -103,6 +118,11 @@ module Mangadex
103
118
  )
104
119
  end
105
120
 
121
+ class << self
122
+ alias_method :view, :get
123
+ alias_method :edit, :update
124
+ end
125
+
106
126
  sig { params(id: String).returns(T::Boolean) }
107
127
  def add_manga(id)
108
128
  Mangadex::CustomList.add_manga(id, list_id: self.id)
@@ -0,0 +1,141 @@
1
+ # typed: true
2
+ module Mangadex
3
+ module Internal
4
+ class Context
5
+ extend T::Sig
6
+
7
+ sig { returns(T::Array[Mangadex::ContentRating]) }
8
+ attr_accessor :allowed_content_ratings, :ignore_user
9
+
10
+ def initialize
11
+ @allowed_content_ratings = Mangadex.configuration.default_content_ratings
12
+ end
13
+
14
+ sig { returns(T.nilable(String)) }
15
+ def version
16
+ @version ||= Mangadex::Api::VersionChecker.check_mangadex_version
17
+ end
18
+
19
+ sig { returns(T.nilable(Mangadex::Api::User)) }
20
+ def user
21
+ @ignore_user ? nil : @user&.with_valid_session
22
+ rescue Mangadex::Errors::UnauthorizedError
23
+ warn("A user is present but not authenticated!")
24
+ nil
25
+ end
26
+
27
+ sig { returns(T::Array[Mangadex::Tag]) }
28
+ def tags
29
+ @tags ||= Mangadex::Tag.list.data
30
+ end
31
+
32
+ sig { params(user: T.nilable(T.any(Hash, Mangadex::Api::User, Mangadex::User)), block: T.proc.returns(T.untyped)).returns(T.untyped) }
33
+ def with_user(user, &block)
34
+ temp_set_value("user", user) do
35
+ yield
36
+ end
37
+ end
38
+
39
+ sig { params(block: T.proc.returns(T.untyped)).returns(T.untyped) }
40
+ def without_user(&block)
41
+ temp_set_value("ignore_user", true) do
42
+ yield
43
+ end
44
+ end
45
+
46
+ sig { params(user: T.nilable(T.untyped)).void }
47
+ def user=(user)
48
+ if user.is_a?(Mangadex::Api::User)
49
+ @user = user
50
+ elsif user.is_a?(Mangadex::User)
51
+ @user = Mangadex::Api::User.new(
52
+ mangadex_user_id: user.id,
53
+ data: user,
54
+ )
55
+ elsif user.is_a?(Hash)
56
+ user = Mangadex::Internal::Definition.validate(user, {
57
+ mangadex_user_id: { accepts: String, required: true },
58
+ session: { accepts: String },
59
+ refresh: { accepts: String },
60
+ })
61
+
62
+ @user = Mangadex::Api::User.new(
63
+ mangadex_user_id: user[:mangadex_user_id],
64
+ session: user[:session],
65
+ refresh: user[:refresh],
66
+ )
67
+ elsif user_object?(user)
68
+ @user = Mangadex::Api::User.new(
69
+ mangadex_user_id: user.mangadex_user_id.to_s,
70
+ session: user.session,
71
+ refresh: user.refresh,
72
+ data: user,
73
+ )
74
+ elsif user.nil?
75
+ @user = nil
76
+ else
77
+ raise TypeError, "Invalid user type."
78
+ end
79
+ end
80
+
81
+ def allow_content_ratings(*content_ratings, &block)
82
+ content_ratings = Mangadex::ContentRating.parse(Array(content_ratings))
83
+ if block_given?
84
+ content_ratings = Mangadex.context.allowed_content_ratings if content_ratings.empty?
85
+
86
+ # set temporarily
87
+ temp_set_value("allowed_content_ratings", content_ratings) do
88
+ yield
89
+ end
90
+ elsif content_ratings.any?
91
+ # set "permanently"
92
+ @allowed_content_ratings = content_ratings
93
+ else
94
+ # This is to throw an exception prompting to pass a block if there no params.
95
+ yield
96
+ end
97
+ end
98
+
99
+ def with_allowed_content_ratings(*other_content_ratings, &block)
100
+ T.unsafe(self).allow_content_ratings(*(allowed_content_ratings + other_content_ratings)) do
101
+ yield
102
+ end
103
+ end
104
+
105
+ # Only recommended for development and debugging only
106
+ def force_raw_requests(&block)
107
+ if block_given?
108
+ temp_set_value("force_raw_requests", true) do
109
+ yield
110
+ end
111
+ else
112
+ !!@force_raw_requests
113
+ end
114
+ end
115
+
116
+ private
117
+
118
+ def user_object?(user)
119
+ return false if user.nil?
120
+
121
+ missing_methods = [:session, :refresh, :mangadex_user_id] - user.methods
122
+ return true if missing_methods.empty?
123
+
124
+ warn("Potential user object #{user} is missing #{missing_methods}")
125
+ false
126
+ end
127
+
128
+ def temp_set_value(name, value, &block)
129
+ setter_method_name = "#{name}="
130
+
131
+ current_value = send(name)
132
+ send(setter_method_name, value)
133
+ response = yield
134
+ send(setter_method_name, current_value)
135
+ response
136
+ ensure
137
+ send(setter_method_name, current_value) if current_value
138
+ end
139
+ end
140
+ end
141
+ end
@@ -120,6 +120,19 @@ module Mangadex
120
120
  )
121
121
  end
122
122
 
123
+ def must(*args)
124
+ args = args.each_with_index.map do |arg, index|
125
+ ["arg_at_position_#{index}".to_sym, arg]
126
+ end.to_h
127
+
128
+ definition = args.keys.map do |key|
129
+ [key, { required: true }]
130
+ end.to_h
131
+
132
+ validate(args, definition)
133
+ args.values
134
+ end
135
+
123
136
  def validate(args, definition)
124
137
  args = Hash(args).with_indifferent_access
125
138
  definition = Hash(definition).with_indifferent_access
@@ -13,9 +13,9 @@ module Mangadex
13
13
  attr_accessor :path, :headers, :payload, :method, :raw
14
14
  attr_reader :response
15
15
 
16
- def self.get(path, params={}, auth: false, headers: nil, raw: false)
16
+ def self.get(path, params={}, auth: false, headers: nil, raw: false, content_rating: false)
17
17
  new(
18
- path_with_params(path, params),
18
+ path_with_params(path, params, content_rating),
19
19
  method: :get,
20
20
  headers: headers,
21
21
  payload: nil,
@@ -54,7 +54,7 @@ module Mangadex
54
54
  payload_details = request_payload ? "Payload: #{request_payload}" : "{no-payload}"
55
55
  puts("[#{self.class.name}] #{method.to_s.upcase} #{request_url} #{payload_details}")
56
56
 
57
- raise Mangadex::UserNotLoggedIn.new if auth && Mangadex::Api::Context.user.nil?
57
+ raise Mangadex::Errors::UserNotLoggedIn.new if auth && Mangadex.context.user.nil?
58
58
 
59
59
  start_time = Time.now
60
60
 
@@ -62,13 +62,17 @@ module Mangadex
62
62
  end_time = Time.now
63
63
  elapsed_time = ((end_time - start_time) * 1000).to_i
64
64
  puts("[#{self.class.name}] took #{elapsed_time} ms")
65
+
66
+ raw_request = raw || Mangadex.context.force_raw_requests
65
67
 
66
- if @response.body
67
- raw ? @response.body : Mangadex::Api::Response.coerce(JSON.parse(@response.body))
68
+ if (body = @response.body)
69
+ raw_request ? try_json(body) : Mangadex::Api::Response.coerce(try_json(body))
68
70
  end
71
+ rescue RestClient::Unauthorized => error
72
+ raise Errors::UnauthorizedError.new(Mangadex::Api::Response.coerce(try_json(error.response.body)))
69
73
  rescue RestClient::Exception => error
70
- if error.response.body
71
- raw ? error.response.body : Mangadex::Api::Response.coerce(JSON.parse(error.response.body)) rescue raise error
74
+ if (body = error.response.body)
75
+ raw_request ? try_json(body) : Mangadex::Api::Response.coerce(JSON.parse(body)) rescue raise error
72
76
  else
73
77
  raise error
74
78
  end
@@ -76,7 +80,8 @@ module Mangadex
76
80
 
77
81
  private
78
82
 
79
- def self.path_with_params(path, params)
83
+ def self.path_with_params(path, params, content_rating)
84
+ params = content_rating ? self.with_content_rating(params) : params
80
85
  return path if params.blank?
81
86
 
82
87
  params = params.deep_transform_keys do |key|
@@ -85,6 +90,14 @@ module Mangadex
85
90
  "#{path}?#{params.to_query}"
86
91
  end
87
92
 
93
+ def self.with_content_rating(data)
94
+ content_rating = data.has_key?(:content_rating) ? data[:content_rating] : []
95
+ Mangadex.context.allow_content_ratings(*content_rating) do
96
+ data[:content_rating] = Mangadex.context.allowed_content_ratings
97
+ end
98
+ data
99
+ end
100
+
88
101
  def request_url
89
102
  request_path = path.start_with?('/') ? path : "/#{path}"
90
103
  "#{BASE_URI}#{request_path}"
@@ -97,10 +110,10 @@ module Mangadex
97
110
  end
98
111
 
99
112
  def request_headers
100
- return headers if Mangadex::Api::Context.user.nil?
113
+ return headers if Mangadex.context.user.nil?
101
114
 
102
115
  headers.merge({
103
- Authorization: Mangadex::Api::Context.user.with_valid_session.session,
116
+ Authorization: Mangadex.context.user.with_valid_session.session,
104
117
  })
105
118
  end
106
119
 
@@ -116,6 +129,12 @@ module Mangadex
116
129
 
117
130
  raise "Invalid method: #{method}. Must be one of: #{ALLOWED_METHODS}"
118
131
  end
132
+
133
+ def try_json(body)
134
+ JSON.parse(body)
135
+ rescue JSON::ParserError
136
+ body
137
+ end
119
138
  end
120
139
  end
121
140
  end
@@ -11,7 +11,8 @@ module Mangadex
11
11
  :id,
12
12
  :type,
13
13
  :attributes,
14
- :relationships
14
+ :relationships,
15
+ :related_type
15
16
 
16
17
  class_methods do
17
18
  USING_ATTRIBUTES = {}
@@ -30,7 +31,7 @@ module Mangadex
30
31
  self.name.split('::').last.underscore
31
32
  end
32
33
 
33
- def from_data(data)
34
+ def from_data(data, related_type: nil)
34
35
  base_class_name = self.name.gsub('::', '_')
35
36
  klass_name = self.name
36
37
  target_attributes_class_name = "#{base_class_name}_Attributes"
@@ -65,6 +66,7 @@ module Mangadex
65
66
  id: data['id'],
66
67
  type: data['type'] || self.type,
67
68
  attributes: attributes,
69
+ related_type: related_type,
68
70
  }
69
71
 
70
72
  initialize_hash.merge!({relationships: relationships}) if relationships.present?
@@ -110,6 +112,13 @@ module Mangadex
110
112
  else
111
113
  super
112
114
  end
115
+ elsif !related_type.nil?
116
+ return super unless method_name.end_with?("?")
117
+
118
+ looking_for_related = method_name.to_s.split("?").first
119
+ return super unless Mangadex::Relationship::RELATED_VALUES.include?(looking_for_related)
120
+
121
+ related_type == looking_for_related
113
122
  else
114
123
  super
115
124
  end
@@ -1,3 +1,4 @@
1
1
  # typed: strict
2
+ require_relative "internal/context"
2
3
  require_relative "internal/request"
3
4
  require_relative "internal/definition"