class WCC::Contentful::ContentTypeIndexer

Attributes

types[R]

Public Class Methods

from_json_schema(schema) click to toggle source
# File lib/wcc/contentful/content_type_indexer.rb, line 16
def from_json_schema(schema)
  new.tap do |ixr|
    schema.each { |type| ixr.index(type) }
  end
end
load(schema_file) click to toggle source
# File lib/wcc/contentful/content_type_indexer.rb, line 10
def load(schema_file)
  from_json_schema(
    JSON.parse(File.read(schema_file))['contentTypes']
  )
end
new() click to toggle source
# File lib/wcc/contentful/content_type_indexer.rb, line 25
def initialize
  @types = IndexedRepresentation.new({
    'Asset' => create_asset_type
  })
end

Public Instance Methods

create_asset_type() click to toggle source

hardcoded because the Asset type is a “magic type” in their system

# File lib/wcc/contentful/content_type_indexer.rb, line 57
def create_asset_type
  IndexedRepresentation::ContentType.new({
    name: 'Asset',
    content_type: 'Asset',
    fields: {
      'title' => { name: 'title', type: :String },
      'description' => { name: 'description', type: :String },
      'file' => { name: 'file', type: :Json }
    }
  })
end
create_type(content_type_id, fields) click to toggle source
# File lib/wcc/contentful/content_type_indexer.rb, line 42
def create_type(content_type_id, fields)
  content_type = IndexedRepresentation::ContentType.new({
    name: constant_from_content_type(content_type_id),
    content_type: content_type_id
  })

  fields.each do |f|
    field = create_field(f)
    content_type.fields[field.name] = field
  end

  content_type
end
index(content_type) click to toggle source
# File lib/wcc/contentful/content_type_indexer.rb, line 31
def index(content_type)
  content_type =
    if content_type.respond_to?(:fields)
      create_type(content_type.id, content_type.fields)
    else
      create_type(content_type.dig('sys', 'id'), content_type['fields'])
    end

  @types[content_type.content_type] = content_type
end

Private Instance Methods

create_field(field) click to toggle source
# File lib/wcc/contentful/content_type_indexer.rb, line 71
def create_field(field)
  if field.respond_to?(:raw)
    create_field_from_raw(field.raw)
  elsif field.respond_to?(:to_h)
    create_field_from_raw(field.to_h)
  else
    create_field_from_managed(field)
  end
end
create_field_from_managed(managed_field) click to toggle source
# File lib/wcc/contentful/content_type_indexer.rb, line 81
def create_field_from_managed(managed_field)
  field = IndexedRepresentation::Field.new({
    name: managed_field.id,
    type: find_field_type(managed_field),
    required: managed_field.required
  })
  field.array = true if managed_field.type == 'Array'

  if field.type == :Link
    validations =
      if field.array
        managed_field.items.validations
      else
        managed_field.validations
      end
    field.link_types = resolve_managed_link_types(validations) if validations.present?
  end
  field
end
create_field_from_raw(raw_field) click to toggle source
# File lib/wcc/contentful/content_type_indexer.rb, line 101
def create_field_from_raw(raw_field)
  field_name = raw_field['id']
  field = IndexedRepresentation::Field.new({
    name: field_name,
    type: find_field_type(raw_field),
    required: raw_field['required']
  })
  field.array = true if raw_field['type'] == 'Array'

  if field.type == :Link
    validations =
      if field.array
        raw_field.dig('items', 'validations')
      else
        raw_field['validations']
      end
    field.link_types = resolve_raw_link_types(validations) if validations.present?
  end
  field
end
find_field_type(field) click to toggle source
# File lib/wcc/contentful/content_type_indexer.rb, line 122
def find_field_type(field)
  # 'Symbol' | 'Text' | 'Integer' | 'Number' | 'Date' | 'Boolean' |
  #  'Object' | 'Location' | 'Array' | 'Link'
  case raw_type = field.try(:type) || field['type']
  when 'Symbol', 'Text'
    :String
  when 'Integer'
    :Int
  when 'Number'
    :Float
  when 'Date'
    :DateTime
  when 'Boolean'
    :Boolean
  when 'Object'
    :Json
  when 'Location'
    :Coordinates
  when 'Array'
    find_field_type(field.try(:items) || field['items'])
  when 'Link'
    case link_type = field.try(:link_type) || field['linkType']
    when 'Entry'
      :Link
    when 'Asset'
      :Asset
    else
      raise ArgumentError,
        "Unknown link type #{link_type} for field #{field.try(:id) || field['id']}"
    end
  else
    raise ArgumentError, "unknown field type #{raw_type} for field #{field.try(:id) || field['id']}"
  end
end