Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
167 changes: 82 additions & 85 deletions lib/intercom-rails/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,62 +2,8 @@

module IntercomRails

class ConfigSingleton

def self.config_accessor(*args, &block)
config_reader(*args)
config_writer(*args, &block)
end

def self.meta_class
class << self; self end
end

def self.config_reader(name)
meta_class.send(:define_method, name) do
instance_variable_get("@#{name}")
end
end

def self.config_writer(name, &block)
meta_class.send(:define_method, "#{name}=") do |value|
validate(name, value, block)
instance_variable_set("@#{name}", value)
end
end

def self.config_group(name, &block)
camelized_name = name.to_s.classify
group = self.const_set(camelized_name, Class.new(self))

meta_class.send(:define_method, name) do
group
end

group.send(:instance_variable_set, :@underscored_class_name, name)
group.instance_eval(&block)
end

private

def self.validate(name, value, block)
return unless block
args = [value]
if block.arity > 1
field_name = underscored_class_name ? "#{underscored_class_name}.#{name}" : name
args << field_name
end
block.call(*args)
end

def self.underscored_class_name
@underscored_class_name
end

end

class Config < ConfigSingleton

class Config
# Validators (moved outside of class << self for accessibility)
CUSTOM_DATA_VALIDATOR = Proc.new do |custom_data, field_name|
case custom_data
when Hash
Expand All @@ -79,7 +25,7 @@ class Config < ConfigSingleton
end

IS_ARAY_OF_PROC_VALIDATOR = Proc.new do |data, field_name|
raise ArgumentError, "#{field_name} data should be a proc or an array of proc" unless data.all? { |value| value.kind_of?(Proc)}
raise ArgumentError, "#{field_name} data should be a proc or an array of proc" unless data.all? { |value| value.kind_of?(Proc)}
end

IS_PROC_OR_ARRAY_OF_PROC_VALIDATOR = Proc.new do |data, field_name|
Expand All @@ -90,69 +36,120 @@ class Config < ConfigSingleton
end
end

def self.reset!
to_reset = self.constants.map {|c| const_get c}
to_reset << self
class << self

to_reset.each do |configer|
configer.instance_variables.each do |var|
configer.send(:remove_instance_variable, var)
# Helper to create accessor with validation
def config_accessor(name, validator: nil)
attr_name = :"@#{name}"

# Define getter
define_singleton_method(name) do
instance_variable_get(attr_name)
end

# Define setter with validation
define_singleton_method("#{name}=") do |value|
if validator
field_name = @underscored_class_name ? "#{@underscored_class_name}.#{name}" : name.to_s
args = validator.arity > 1 ? [value, field_name] : [value]
validator.call(*args)
end
instance_variable_set(attr_name, value)
end
end

def reset!
to_reset = [self] + constants.select { |c| const_get(c).is_a?(Class) && const_get(c) < Config }.map { |c| const_get(c) }

to_reset.each do |configer|
configer.instance_variables.each do |var|
configer.send(:remove_instance_variable, var)
end
end
end

def api_key=(*)
warn "Setting an Intercom API key is no longer supported; remove the `config.api_key = ...` line from config/initializers/intercom.rb"
end
end

# Main configuration options
config_accessor :app_id
config_accessor :session_duration
config_accessor :api_secret
config_accessor :library_url
config_accessor :enabled_environments, &ARRAY_VALIDATOR
config_accessor :enabled_environments, validator: ARRAY_VALIDATOR
config_accessor :include_for_logged_out_users
config_accessor :hide_default_launcher
config_accessor :api_base
config_accessor :encrypted_mode

def self.api_key=(*)
warn "Setting an Intercom API key is no longer supported; remove the `config.api_key = ...` line from config/initializers/intercom.rb"
end
# User configuration group
class User < Config
@underscored_class_name = :user

config_group :user do
config_accessor :current, &IS_PROC_OR_ARRAY_OF_PROC_VALIDATOR
config_accessor :exclude_if, &IS_PROC_VALIDATOR
config_accessor :model, &IS_PROC_VALIDATOR
config_accessor :lead_attributes, &ARRAY_VALIDATOR
config_accessor :custom_data, &CUSTOM_DATA_VALIDATOR
config_accessor :current, validator: IS_PROC_OR_ARRAY_OF_PROC_VALIDATOR
config_accessor :exclude_if, validator: IS_PROC_VALIDATOR
config_accessor :model, validator: IS_PROC_VALIDATOR
config_accessor :lead_attributes, validator: ARRAY_VALIDATOR
config_accessor :custom_data, validator: CUSTOM_DATA_VALIDATOR

def self.company_association=(*)
warn "Setting a company association is no longer supported; remove the `config.user.company_association = ...` line from config/initializers/intercom.rb"
end
end

config_group :company do
config_accessor :current, &IS_PROC_VALIDATOR
config_accessor :exclude_if, &IS_PROC_VALIDATOR
config_accessor :plan, &IS_PROC_VALIDATOR
config_accessor :monthly_spend, &IS_PROC_VALIDATOR
config_accessor :custom_data, &CUSTOM_DATA_VALIDATOR
# Company configuration group
class Company < Config
@underscored_class_name = :company

config_accessor :current, validator: IS_PROC_VALIDATOR
config_accessor :exclude_if, validator: IS_PROC_VALIDATOR
config_accessor :plan, validator: IS_PROC_VALIDATOR
config_accessor :monthly_spend, validator: IS_PROC_VALIDATOR
config_accessor :custom_data, validator: CUSTOM_DATA_VALIDATOR
end

config_group :inbox do
# Inbox configuration group
class Inbox < Config
@underscored_class_name = :inbox

config_accessor :counter # Keep this for backwards compatibility
config_accessor :custom_activator
config_accessor :style do |value|
config_accessor :style, validator: Proc.new { |value|
raise ArgumentError, "inbox.style must be one of :default or :custom" unless [:default, :custom].include?(value)
end
}
end

config_group :jwt do
# JWT configuration group
class Jwt < Config
@underscored_class_name = :jwt

config_accessor :enabled
config_accessor :expiry
config_accessor :signed_user_fields do |value|
config_accessor :signed_user_fields, validator: Proc.new { |value|
unless value.nil? || (value.kind_of?(Array) && value.all? { |v| v.kind_of?(Symbol) || v.kind_of?(String) })
raise ArgumentError, "jwt.signed_user_fields must be an array of symbols or strings"
end
end
}
end

# Methods to access configuration groups
def self.user
User
end

def self.company
Company
end

def self.inbox
Inbox
end

def self.jwt
Jwt
end
end

end