mirror of https://github.com/docusealco/docuseal
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
119 lines
3.4 KiB
119 lines
3.4 KiB
require "uber/delegates"
|
|
require "uber/callable"
|
|
require "declarative/schema"
|
|
|
|
require "representable/option"
|
|
require "representable/config"
|
|
require "representable/definition"
|
|
require "representable/declarative"
|
|
require "representable/deserializer"
|
|
require "representable/serializer"
|
|
require "representable/binding"
|
|
require "representable/pipeline"
|
|
require "representable/insert" # Pipeline::Insert
|
|
require "representable/cached"
|
|
require "representable/for_collection"
|
|
require "representable/represent"
|
|
|
|
module Representable
|
|
autoload :Binding, 'representable/binding'
|
|
autoload :HashMethods, 'representable/hash_methods'
|
|
autoload :Decorator, 'representable/decorator'
|
|
|
|
autoload :Hash, 'representable/hash'
|
|
autoload :JSON, 'representable/json'
|
|
autoload :Object, 'representable/object'
|
|
autoload :YAML, 'representable/yaml'
|
|
autoload :XML, 'representable/xml'
|
|
|
|
|
|
attr_writer :representable_attrs
|
|
|
|
def self.included(base)
|
|
base.class_eval do
|
|
extend Declarative
|
|
# make Representable horizontally and vertically inheritable.
|
|
extend ModuleExtensions, ::Declarative::Heritage::Inherited, ::Declarative::Heritage::Included
|
|
extend ClassMethods
|
|
extend ForCollection
|
|
extend Represent
|
|
end
|
|
end
|
|
|
|
private
|
|
# Reads values from +doc+ and sets properties accordingly.
|
|
def update_properties_from(doc, options, format)
|
|
propagated_options = normalize_options(**options)
|
|
|
|
representable_map!(doc, propagated_options, format, :uncompile_fragment)
|
|
represented
|
|
end
|
|
|
|
# Compiles the document going through all properties.
|
|
def create_representation_with(doc, options, format)
|
|
propagated_options = normalize_options(**options)
|
|
|
|
representable_map!(doc, propagated_options, format, :compile_fragment)
|
|
doc
|
|
end
|
|
|
|
|
|
def representable_map(options, format)
|
|
Binding::Map.new(representable_bindings_for(format, options))
|
|
end
|
|
|
|
def representable_map!(doc, options, format, method)
|
|
options = {doc: doc, options: options, represented: represented, decorator: self}
|
|
|
|
representable_map(options, format).(method, options) # .(:uncompile_fragment, options)
|
|
end
|
|
|
|
def representable_bindings_for(format, options)
|
|
representable_attrs.collect {|definition| format.build(definition) }
|
|
end
|
|
|
|
def normalize_options(user_options: {}, **options)
|
|
{ user_options: user_options }.merge(options)
|
|
end
|
|
|
|
# Prepares options for a particular nested representer.
|
|
# This is used in Serializer and Deserializer.
|
|
OptionsForNested = ->(options, binding) do
|
|
child_options = {user_options: options[:user_options], }
|
|
|
|
# wrap:
|
|
child_options[:wrap] = binding[:wrap] unless binding[:wrap].nil?
|
|
|
|
# nested params:
|
|
child_options.merge!(options[binding.name.to_sym]) if options[binding.name.to_sym]
|
|
child_options
|
|
end
|
|
|
|
def representable_attrs
|
|
@representable_attrs ||= self.class.definitions
|
|
end
|
|
|
|
def representation_wrap(options = {})
|
|
representable_attrs.wrap_for(represented, options)
|
|
end
|
|
|
|
def represented
|
|
self
|
|
end
|
|
|
|
module ModuleExtensions
|
|
# Copies the representable_attrs reference to the extended object.
|
|
# Note that changing attrs in the instance will affect the class configuration.
|
|
def extended(object)
|
|
super
|
|
object.representable_attrs=(representable_attrs) # yes, we want a hard overwrite here and no inheritance.
|
|
end
|
|
end
|
|
|
|
module ClassMethods
|
|
def prepare(represented)
|
|
represented.extend(self)
|
|
end
|
|
end
|
|
end
|