Module: GraphQL::Client::CollocatedEnforcement

Extended by:
CollocatedEnforcement
Included in:
GraphQL::Client, CollocatedEnforcement
Defined in:
lib/graphql/client/collocated_enforcement.rb

Overview

Enforcements collocated object access best practices.

Instance Method Summary collapse

Instance Method Details

#allow_noncollocated_callersObject

Public: Ignore collocated caller enforcement for the scope of the block.



18
19
20
21
22
23
# File 'lib/graphql/client/collocated_enforcement.rb', line 18

def allow_noncollocated_callers
  Thread.current[:query_result_caller_location_ignore] = true
  yield
ensure
  Thread.current[:query_result_caller_location_ignore] = nil
end

#enforce_collocated_callers(mod, methods, path) ⇒ Object

Internal: Decorate method with collocated caller enforcement.

mod - Target Module/Class methods - Array of Symbol method names path - String filename to assert calling from

Returns nothing.



49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/graphql/client/collocated_enforcement.rb', line 49

def enforce_collocated_callers(mod, methods, path)
  mod.prepend(Module.new do
    methods.each do |method|
      define_method(method) do |*args, &block|
        location = caller_locations(1, 1)[0]
        CollocatedEnforcement.verify_collocated_path(location, path, method) do
          super(*args, &block)
        end
      end
    end
  end)
end

#verify_collocated_path(location, path, method = "method") ⇒ Object



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/graphql/client/collocated_enforcement.rb', line 25

def verify_collocated_path(location, path, method = "method")
  return yield if Thread.current[:query_result_caller_location_ignore]

  if (location.path != path) && !(WHITELISTED_GEM_NAMES.any? { |g| location.path.include?("gems/#{g}") })
    error = NonCollocatedCallerError.new("#{method} was called outside of '#{path}' https://github.com/github-community-projects/graphql-client/blob/master/guides/collocated-call-sites.md")
    error.set_backtrace(caller(2))
    raise error
  end

  begin
    Thread.current[:query_result_caller_location_ignore] = true
    yield
  ensure
    Thread.current[:query_result_caller_location_ignore] = nil
  end
end