Module: GraphQL::Client::CollocatedEnforcement

Included in:
GraphQL::Client
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.



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

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.



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/graphql/client/collocated_enforcement.rb', line 30

def enforce_collocated_callers(mod, methods, path)
  mod.prepend(Module.new do
    methods.each do |method|
      define_method(method) do |*args, &block|
        return super(*args, &block) if Thread.current[:query_result_caller_location_ignore]

        locations = caller_locations(1, 1)

        if (locations.first.path != path) && !(caller_locations.any? { |cl| WHITELISTED_GEM_NAMES.any? { |g| cl.path.include?("gems/#{g}") } })
          error = NonCollocatedCallerError.new("#{method} was called outside of '#{path}' https://git.io/v1syX")
          error.set_backtrace(caller(1))
          raise error
        end

        begin
          Thread.current[:query_result_caller_location_ignore] = true
          super(*args, &block)
        ensure
          Thread.current[:query_result_caller_location_ignore] = nil
        end
      end
    end
  end)
end