class WCC::Contentful::DownloadsSchema

Public Class Methods

call(file = nil, management_client: nil) click to toggle source
# File lib/wcc/contentful/downloads_schema.rb, line 6
def self.call(file = nil, management_client: nil)
  new(file, management_client: management_client).call
end
new(file = nil, management_client: nil) click to toggle source
# File lib/wcc/contentful/downloads_schema.rb, line 10
def initialize(file = nil, management_client: nil)
  @client = management_client || WCC::Contentful::Services.instance.management_client
  @file = file || WCC::Contentful.configuration&.schema_file
  raise ArgumentError, 'Please configure your management token' unless @client
  raise ArgumentError, 'Please pass filename or call WCC::Contentful.configure' unless @file
end

Public Instance Methods

call() click to toggle source
# File lib/wcc/contentful/downloads_schema.rb, line 17
def call
  return unless needs_update?

  update!
end
content_types() click to toggle source
# File lib/wcc/contentful/downloads_schema.rb, line 52
def content_types
  @content_types ||=
    @client.content_types(limit: 1000)
      .items
      .map { |ct| strip_sys(ct) }
      .sort_by { |ct| ct.dig('sys', 'id') }
end
editor_interfaces() click to toggle source
# File lib/wcc/contentful/downloads_schema.rb, line 60
def editor_interfaces
  @editor_interfaces ||=
    content_types
      .map { |ct| @client.editor_interface(ct.dig('sys', 'id')).raw }
      .map { |i| sort_controls(strip_sys(i)) }
      .sort_by { |i| i.dig('sys', 'contentType', 'sys', 'id') }
end
needs_update?() click to toggle source
# File lib/wcc/contentful/downloads_schema.rb, line 32
def needs_update?
  return true unless File.exist?(@file)

  contents =
    begin
      JSON.parse(File.read(@file))
    rescue JSON::ParserError
      return true
    end

  existing_cts = contents['contentTypes'].sort_by { |ct| ct.dig('sys', 'id') }
  return true unless content_types.count == existing_cts.count
  return true unless deep_contains_all(content_types, existing_cts)

  existing_eis = contents['editorInterfaces'].sort_by { |i| i.dig('sys', 'contentType', 'sys', 'id') }
  return true unless editor_interfaces.count == existing_eis.count

  !deep_contains_all(editor_interfaces, existing_eis)
end
update!() click to toggle source
# File lib/wcc/contentful/downloads_schema.rb, line 23
def update!
  FileUtils.mkdir_p(File.dirname(@file))

  File.write(@file, format_json({
    'contentTypes' => content_types,
    'editorInterfaces' => editor_interfaces
  }))
end

Private Instance Methods

deep_contains_all(expected, actual) click to toggle source
# File lib/wcc/contentful/downloads_schema.rb, line 85
def deep_contains_all(expected, actual)
  if expected.is_a? Array
    expected.each_with_index do |val, i|
      return false unless actual[i]
      return false unless deep_contains_all(val, actual[i])
    end
    true
  elsif expected.is_a? Hash
    expected.each do |(key, val)|
      return false unless actual.key?(key)
      return false unless deep_contains_all(val, actual[key])
    end
    true
  else
    expected == actual
  end
end
format_json(hash) click to toggle source
# File lib/wcc/contentful/downloads_schema.rb, line 103
def format_json(hash)
  json_string = JSON.pretty_generate(hash)

  # The pretty_generate format differs from contentful-shell and nodejs formats
  # only in its treatment of empty arrays in the "validations" field.
  json_string = json_string.gsub(/\[\n\n\s+\]/, '[]')
  # contentful-shell also adds a newline at the end.
  json_string + "\n"
end
sort_controls(editor_interface) click to toggle source
# File lib/wcc/contentful/downloads_schema.rb, line 76
def sort_controls(editor_interface)
  {
    'sys' => editor_interface['sys'],
    'controls' => editor_interface['controls']
      .sort_by { |c| c['fieldId'] }
      .map { |c| c.slice('fieldId', 'settings', 'widgetId') }
  }
end
strip_sys(obj) click to toggle source
# File lib/wcc/contentful/downloads_schema.rb, line 70
def strip_sys(obj)
  obj.merge!({
    'sys' => obj['sys'].slice('id', 'type', 'contentType')
  })
end