class Paradocs::Schema
Attributes
default_field_policies[R]
definitions[R]
environment[RW]
expansions[R]
ignored_field_keys[R]
options[R]
structure_builder[R]
subschemes[R]
Public Class Methods
new(options={}, &block)
click to toggle source
# File lib/paradocs/schema.rb, line 11 def initialize(options={}, &block) @options = options @fields = {} @subschemes = {} @definitions = [] @definitions << block if block_given? @default_field_policies = [] @ignored_field_keys = [] @expansions = {} @structure_builder = Paradocs::Extensions::Structure.new(self) end
Public Instance Methods
clone()
click to toggle source
# File lib/paradocs/schema.rb, line 90 def clone instance = self.class.new(options) copy_into instance end
coerce(val, _, context)
click to toggle source
# File lib/paradocs/schema.rb, line 153 def coerce(val, _, context) flush! if val.is_a?(Array) val.map.with_index do |v, idx| subcontext = context.sub(idx) out = coerce_one(v, subcontext) resolve_expansions(v, out, subcontext) end else out = coerce_one(val, context) resolve_expansions(val, out, context) end end
copy_into(instance)
click to toggle source
# File lib/paradocs/schema.rb, line 102 def copy_into(instance) instance.policy(*default_field_policies) if default_field_policies.any? definitions.each do |d| instance.definitions << d end subschemes.each { |name, subsc| instance.subschema(name, subsc) } instance.ignore *ignored_field_keys instance end
eligible?(value, key, payload)
click to toggle source
# File lib/paradocs/schema.rb, line 141 def eligible?(value, key, payload) payload.key? key end
example_payloads(&block)
click to toggle source
# File lib/paradocs/schema.rb, line 38 def example_payloads(&block) @example_payloads ||= Paradocs::Extensions::PayloadBuilder.new(self).build!(&block) end
expand(exp, &block)
click to toggle source
# File lib/paradocs/schema.rb, line 129 def expand(exp, &block) expansions[exp] = block self end
field(field_or_key)
click to toggle source
# File lib/paradocs/schema.rb, line 115 def field(field_or_key) f, key = if field_or_key.kind_of?(Field) [field_or_key, field_or_key.key] else [Field.new(field_or_key), field_or_key.to_sym] end if ignored_field_keys.include?(f.key) f else @fields[key] = apply_default_field_policies_to(f) end end
fields()
click to toggle source
# File lib/paradocs/schema.rb, line 69 def fields apply! @fields end
flush!()
click to toggle source
# File lib/paradocs/schema.rb, line 167 def flush! @fields = {} @applied = false end
ignore(*field_keys, &block)
click to toggle source
# File lib/paradocs/schema.rb, line 81 def ignore(*field_keys, &block) @ignored_field_keys += field_keys @ignored_field_keys.uniq! definitions << block if block_given? self end
merge(other_schema)
click to toggle source
# File lib/paradocs/schema.rb, line 95 def merge(other_schema) instance = self.class.new(options.merge(other_schema.options)) copy_into(instance) other_schema.copy_into(instance) end
meta_data()
click to toggle source
# File lib/paradocs/schema.rb, line 149 def meta_data {} end
mutation_by!(key, &block)
click to toggle source
# File lib/paradocs/schema.rb, line 27 def mutation_by!(key, &block) f = @fields.keys.include?(key) ? @fields[key] : field(key).transparent f.mutates_schema!(&block) end
policy(*names, &block)
click to toggle source
# File lib/paradocs/schema.rb, line 74 def policy(*names, &block) @default_field_policies = names definitions << block if block_given? self end
resolve(payload, environment={})
click to toggle source
# File lib/paradocs/schema.rb, line 134 def resolve(payload, environment={}) @environment = environment context = Context.new(nil, Top.new, @environment, subschemes) output = coerce(payload, nil, context) Results.new(output, context.errors, @environment) end
schema()
click to toggle source
# File lib/paradocs/schema.rb, line 23 def schema self end
structure(ignore_transparent: true)
click to toggle source
# File lib/paradocs/schema.rb, line 32 def structure(ignore_transparent: true) flush! structure_builder.ignore_transparent = ignore_transparent structure_builder end
subschema(*args, &block)
click to toggle source
# File lib/paradocs/schema.rb, line 53 def subschema(*args, &block) options = args.last.is_a?(Hash) ? args.last : {} name = args.first.is_a?(Symbol) ? args.shift : Paradocs.config.default_schema_name current_schema = subschemes.fetch(name) { self.class.new } new_schema = if block_given? sc = self.class.new(options) sc.definitions << block sc elsif args.first.is_a?(self.class) args.first else self.class.new(options) end subschemes[name] = current_schema.merge(new_schema) end
valid?(*_)
click to toggle source
# File lib/paradocs/schema.rb, line 145 def valid?(*_) true end
visit(meta_key = nil, &visitor)
click to toggle source
# File lib/paradocs/schema.rb, line 47 def visit(meta_key = nil, &visitor) fields.each_with_object({}) do |(_, field), m| m[field.key] = field.visit(meta_key, &visitor) end end
walk(meta_key = nil, &visitor)
click to toggle source
# File lib/paradocs/schema.rb, line 42 def walk(meta_key = nil, &visitor) r = visit(meta_key, &visitor) Results.new(r, {}, {}) end
Private Instance Methods
apply!()
click to toggle source
# File lib/paradocs/schema.rb, line 228 def apply! return if @applied definitions.each do |d| self.instance_exec(options, &d) end @applied = true end
apply_default_field_policies_to(field)
click to toggle source
# File lib/paradocs/schema.rb, line 224 def apply_default_field_policies_to(field) default_field_policies.reduce(field) {|f, policy_name| f.policy(policy_name) } end
coerce_one(val, context, flds: fields)
click to toggle source
# File lib/paradocs/schema.rb, line 180 def coerce_one(val, context, flds: fields) invoke_subschemes!(val, context, flds: flds) flds.each_with_object({}) do |(_, field), m| r = field.resolve(val, context.sub(field.key)) key = field.meta_data[:alias] || field.key m[key] = r.value if r.eligible? end end
invoke_subschemes!(payload, context, flds: fields)
click to toggle source
# File lib/paradocs/schema.rb, line 189 def invoke_subschemes!(payload, context, flds: fields) invoked_any = false # recoursive definitions call depending on payload flds.clone.each_pair do |_, field| next unless field.expects_mutation? subschema_name = field.subschema_for_mutation(payload, context.environment) subschema = subschemes[subschema_name] || context.subschema(subschema_name) next unless subschema # or may be raise error? subschema.definitions.each { |block| self.instance_exec(&block) } invoked_any = true end # if definitions are applied new subschemes may appear, apply them until they end invoke_subschemes!(payload, context, flds: fields) if invoked_any end
resolve_expansions(payload, into, context)
click to toggle source
# File lib/paradocs/schema.rb, line 210 def resolve_expansions(payload, into, context) expansions.each do |exp, block| payload.each do |key, value| match = exp.match(key.to_s) next unless match fld = MatchContext.new.instance_exec(match, &block) next unless fld into.update(coerce_one({fld.key => value}, context, flds: {fld.key => apply_default_field_policies_to(fld)})) end end into end