Class: SmartBrain::Contracts::ScopeContext

Inherits:
Object
  • Object
show all
Defined in:
lib/smart_brain/contracts/scope_context.rb

Constant Summary collapse

LEGACY_DOMAIN_ID =
'legacy'

Class Method Summary collapse

Class Method Details

.legacy_context(session_id) ⇒ Object



40
41
42
43
# File 'lib/smart_brain/contracts/scope_context.rb', line 40

def self.legacy_context(session_id)
  ref = { type: 'session', id: session_id.to_s }
  { read: [ref], write: [ref], default_write: ref }
end

.normalize(domain_id:, session_id:, scope_context:, allowed_types: ScopeRef::DEFAULT_ALLOWED_TYPES) ⇒ Object

Raises:

  • (ArgumentError)


10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/smart_brain/contracts/scope_context.rb', line 10

def self.normalize(domain_id:, session_id:, scope_context:, allowed_types: ScopeRef::DEFAULT_ALLOWED_TYPES)
  normalized_domain = domain_id.to_s.strip
  if normalized_domain.empty? && scope_context
    raise ArgumentError, 'domain_id is required when scope_context is provided'
  end
  normalized_domain = LEGACY_DOMAIN_ID if normalized_domain.empty?
  raise ArgumentError, 'session_id is required' if session_id.to_s.strip.empty?

  raw = scope_context || legacy_context(session_id)
  read = Array(raw[:read] || raw['read']).map { |ref| ScopeRef.normalize(ref, allowed_types: allowed_types) }
  raise ArgumentError, 'scope_context.read must not be empty' if read.empty?

  keys = read.map { |ref| "#{ref[:type]}:#{ref[:id]}" }
  duplicates = keys.tally.select { |_key, count| count > 1 }.keys
  raise ArgumentError, "duplicate scope refs: #{duplicates.join(', ')}" unless duplicates.empty?

  default_write = ScopeRef.normalize(raw[:default_write] || raw['default_write'], allowed_types: allowed_types)
  write_raw = raw.key?(:write) ? raw[:write] : raw['write']
  write = Array(write_raw || [default_write]).map { |ref| ScopeRef.normalize(ref, allowed_types: allowed_types) }
  write_keys = write.map { |ref| "#{ref[:type]}:#{ref[:id]}" }
  write_duplicates = write_keys.tally.select { |_key, count| count > 1 }.keys
  raise ArgumentError, "duplicate writable scope refs: #{write_duplicates.join(', ')}" unless write_duplicates.empty?
  raise ArgumentError, 'scope_context.write must be included in read' unless write_keys.all? { |key| keys.include?(key) }
  unless write_keys.include?("#{default_write[:type]}:#{default_write[:id]}")
    raise ArgumentError, 'scope_context.default_write must be included in write'
  end

  { domain_id: normalized_domain, read: read, write: write, default_write: default_write }
end