dato 0.7.15 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +42 -5
  3. data/.travis.yml +1 -0
  4. data/CHANGELOG.md +4 -0
  5. data/Gemfile +1 -1
  6. data/Rakefile +2 -2
  7. data/TODO.md +28 -0
  8. data/bin/console +3 -3
  9. data/bin/rspec +6 -6
  10. data/dato.gemspec +1 -1
  11. data/exe/dato +3 -3
  12. data/lib/dato.rb +8 -8
  13. data/lib/dato/account/client.rb +2 -2
  14. data/lib/dato/api_client.rb +67 -44
  15. data/lib/dato/api_error.rb +10 -13
  16. data/lib/dato/cli.rb +18 -18
  17. data/lib/dato/dump/dsl/add_to_data_file.rb +1 -1
  18. data/lib/dato/dump/dsl/create_data_file.rb +1 -1
  19. data/lib/dato/dump/dsl/create_post.rb +1 -1
  20. data/lib/dato/dump/dsl/directory.rb +4 -4
  21. data/lib/dato/dump/dsl/root.rb +7 -7
  22. data/lib/dato/dump/format.rb +3 -3
  23. data/lib/dato/dump/format/json.rb +1 -1
  24. data/lib/dato/dump/format/toml.rb +6 -6
  25. data/lib/dato/dump/format/yaml.rb +3 -3
  26. data/lib/dato/dump/operation/add_to_data_file.rb +4 -4
  27. data/lib/dato/dump/operation/create_data_file.rb +3 -3
  28. data/lib/dato/dump/operation/create_post.rb +5 -6
  29. data/lib/dato/dump/operation/directory.rb +1 -1
  30. data/lib/dato/dump/runner.rb +5 -5
  31. data/lib/dato/dump/ssg_detector.rb +18 -20
  32. data/lib/dato/json_api_deserializer.rb +15 -16
  33. data/lib/dato/json_api_serializer.rb +39 -28
  34. data/lib/dato/json_schema_relationships.rb +19 -23
  35. data/lib/dato/json_schema_type.rb +47 -0
  36. data/lib/dato/local/entities_repo.rb +3 -3
  37. data/lib/dato/local/field_type/color.rb +11 -7
  38. data/lib/dato/local/field_type/file.rb +18 -24
  39. data/lib/dato/local/field_type/gallery.rb +1 -1
  40. data/lib/dato/local/field_type/global_seo.rb +4 -7
  41. data/lib/dato/local/field_type/lat_lon.rb +1 -1
  42. data/lib/dato/local/field_type/seo.rb +1 -1
  43. data/lib/dato/local/field_type/structured_text.rb +63 -0
  44. data/lib/dato/local/field_type/theme.rb +2 -2
  45. data/lib/dato/local/field_type/upload_id.rb +5 -5
  46. data/lib/dato/local/field_type/video.rb +9 -15
  47. data/lib/dato/local/item.rb +13 -12
  48. data/lib/dato/local/items_repo.rb +12 -18
  49. data/lib/dato/local/json_api_entity.rb +4 -3
  50. data/lib/dato/local/loader.rb +31 -32
  51. data/lib/dato/local/site.rb +5 -4
  52. data/lib/dato/paginator.rb +4 -4
  53. data/lib/dato/repo.rb +23 -30
  54. data/lib/dato/site/client.rb +5 -5
  55. data/lib/dato/upload/create_upload_path.rb +7 -10
  56. data/lib/dato/upload/file.rb +3 -3
  57. data/lib/dato/upload/image.rb +1 -1
  58. data/lib/dato/utils/build_modular_block.rb +4 -4
  59. data/lib/dato/utils/favicon_tags_builder.rb +10 -10
  60. data/lib/dato/utils/locale_value.rb +1 -1
  61. data/lib/dato/utils/meta_tags/article_modified_time.rb +3 -3
  62. data/lib/dato/utils/meta_tags/article_publisher.rb +2 -2
  63. data/lib/dato/utils/meta_tags/base.rb +6 -6
  64. data/lib/dato/utils/meta_tags/description.rb +4 -4
  65. data/lib/dato/utils/meta_tags/image.rb +4 -5
  66. data/lib/dato/utils/meta_tags/og_locale.rb +2 -2
  67. data/lib/dato/utils/meta_tags/og_site_name.rb +2 -2
  68. data/lib/dato/utils/meta_tags/og_type.rb +3 -3
  69. data/lib/dato/utils/meta_tags/robots.rb +2 -2
  70. data/lib/dato/utils/meta_tags/title.rb +6 -6
  71. data/lib/dato/utils/meta_tags/twitter_card.rb +2 -2
  72. data/lib/dato/utils/meta_tags/twitter_site.rb +2 -2
  73. data/lib/dato/utils/seo_tags_builder.rb +12 -12
  74. data/lib/dato/version.rb +1 -1
  75. metadata +9 -6
data/lib/dato/cli.rb CHANGED
@@ -1,16 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'thor'
4
- require 'dato/dump/runner'
5
- require 'dato/dump/ssg_detector'
6
- require 'listen'
3
+ require "thor"
4
+ require "dato/dump/runner"
5
+ require "dato/dump/ssg_detector"
6
+ require "listen"
7
7
  module Dato
8
8
  class Cli < Thor
9
- package_name 'DatoCMS'
9
+ package_name "DatoCMS"
10
10
 
11
- desc 'dump', 'dumps DatoCMS content into local files'
12
- option :config, default: 'dato.config.rb'
13
- option :token, default: ENV['DATO_API_TOKEN'], required: true
11
+ desc "dump", "dumps DatoCMS content into local files"
12
+ option :config, default: "dato.config.rb"
13
+ option :token, default: ENV["DATO_API_TOKEN"], required: true
14
14
  option :environment, type: :string, required: false
15
15
  option :preview, default: false, type: :boolean
16
16
  option :watch, default: false, type: :boolean
@@ -24,12 +24,12 @@ module Dato
24
24
  options[:token],
25
25
  environment: options[:environment],
26
26
  extra_headers: {
27
- 'X-Reason' => 'dump',
28
- 'X-SSG' => Dump::SsgDetector.new(Dir.pwd).detect
29
- }
27
+ "X-Reason" => "dump",
28
+ "X-SSG" => Dump::SsgDetector.new(Dir.pwd).detect,
29
+ },
30
30
  )
31
31
  loader = Dato::Local::Loader.new(client, preview_mode)
32
- print 'Fetching content from DatoCMS... '
32
+ print "Fetching content from DatoCMS... "
33
33
  loader.load
34
34
 
35
35
  if watch_mode
@@ -51,23 +51,23 @@ module Dato
51
51
  end
52
52
  end
53
53
 
54
- desc 'check', 'checks the presence of a DatoCMS token'
54
+ desc "check", "checks the presence of a DatoCMS token"
55
55
  def check
56
- exit 0 if ENV['DATO_API_TOKEN']
56
+ exit 0 if ENV["DATO_API_TOKEN"]
57
57
 
58
- say 'Site token is not specified!'
58
+ say "Site token is not specified!"
59
59
  token = ask "Please paste your DatoCMS site read-only API token:\n>"
60
60
 
61
61
  if !token || token.empty?
62
- puts 'Missing token'
62
+ puts "Missing token"
63
63
  exit 1
64
64
  end
65
65
 
66
- File.open('.env', 'a') do |file|
66
+ File.open(".env", "a") do |file|
67
67
  file.puts "DATO_API_TOKEN=#{token}"
68
68
  end
69
69
 
70
- say 'Token added to .env file.'
70
+ say "Token added to .env file."
71
71
 
72
72
  exit 0
73
73
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dato/dump/operation/add_to_data_file'
3
+ require "dato/dump/operation/add_to_data_file"
4
4
 
5
5
  module Dato
6
6
  module Dump
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dato/dump/operation/create_data_file'
3
+ require "dato/dump/operation/create_data_file"
4
4
 
5
5
  module Dato
6
6
  module Dump
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dato/dump/operation/create_post'
3
+ require "dato/dump/operation/create_post"
4
4
 
5
5
  module Dato
6
6
  module Dump
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dato/dump/dsl/create_post'
4
- require 'dato/dump/dsl/create_data_file'
5
- require 'dato/dump/dsl/add_to_data_file'
3
+ require "dato/dump/dsl/create_post"
4
+ require "dato/dump/dsl/create_data_file"
5
+ require "dato/dump/dsl/add_to_data_file"
6
6
 
7
7
  module Dato
8
8
  module Dump
@@ -17,7 +17,7 @@ module Dato
17
17
  def initialize(dato, operations, &block)
18
18
  @dato = dato
19
19
  @operations = operations
20
- @self_before_instance_eval = eval 'self', block.binding
20
+ @self_before_instance_eval = eval "self", block.binding
21
21
 
22
22
  instance_eval(&block)
23
23
  end
@@ -1,11 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dato/dump/dsl/directory'
4
- require 'dato/dump/dsl/create_post'
5
- require 'dato/dump/dsl/create_data_file'
6
- require 'dato/dump/dsl/add_to_data_file'
3
+ require "dato/dump/dsl/directory"
4
+ require "dato/dump/dsl/create_post"
5
+ require "dato/dump/dsl/create_data_file"
6
+ require "dato/dump/dsl/add_to_data_file"
7
7
 
8
- require 'dato/dump/operation/directory'
8
+ require "dato/dump/operation/directory"
9
9
 
10
10
  module Dato
11
11
  module Dump
@@ -21,9 +21,9 @@ module Dato
21
21
  @dato = dato
22
22
  @operations = operations
23
23
 
24
- # rubocop:disable Lint/Eval
24
+ # rubocop:disable Security/Eval
25
25
  eval(config_code)
26
- # rubocop:enable Lint/Eval
26
+ # rubocop:enable Security/Eval
27
27
  end
28
28
 
29
29
  def directory(path, &block)
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dato/dump/format/toml'
4
- require 'dato/dump/format/yaml'
5
- require 'dato/dump/format/json'
3
+ require "dato/dump/format/toml"
4
+ require "dato/dump/format/yaml"
5
+ require "dato/dump/format/json"
6
6
 
7
7
  module Dato
8
8
  module Dump
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'json'
3
+ require "json"
4
4
 
5
5
  module Dato
6
6
  module Dump
@@ -1,17 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'active_support/core_ext/hash/keys'
4
- require 'toml'
3
+ require "active_support/core_ext/hash/keys"
4
+ require "toml"
5
5
 
6
6
  class Time
7
- def to_toml(_path = '')
8
- utc.strftime('%Y-%m-%dT%H:%M:%SZ')
7
+ def to_toml(_path = "")
8
+ utc.strftime("%Y-%m-%dT%H:%M:%SZ")
9
9
  end
10
10
  end
11
11
 
12
12
  class Date
13
- def to_toml(_path = '')
14
- strftime('%Y-%m-%d')
13
+ def to_toml(_path = "")
14
+ strftime("%Y-%m-%d")
15
15
  end
16
16
  end
17
17
 
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'active_support/core_ext/hash/keys'
4
- require 'yaml'
3
+ require "active_support/core_ext/hash/keys"
4
+ require "yaml"
5
5
 
6
6
  class Array
7
7
  def deep_stringify_keys
@@ -22,7 +22,7 @@ module Dato
22
22
  module Format
23
23
  module Yaml
24
24
  def self.dump(value)
25
- YAML.dump(value.deep_stringify_keys).chomp.gsub(/^\-+\n/, '')
25
+ YAML.dump(value.deep_stringify_keys).chomp.gsub(/^-+\n/, "")
26
26
  end
27
27
 
28
28
  def self.frontmatter_dump(value)
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dato/dump/format'
3
+ require "dato/dump/format"
4
4
 
5
5
  module Dato
6
6
  module Dump
@@ -24,15 +24,15 @@ module Dato
24
24
  old_content = if File.exist? complete_path
25
25
  ::File.read(complete_path)
26
26
  else
27
- ''
27
+ ""
28
28
  end
29
29
 
30
30
  new_content = old_content.sub(
31
31
  /\n*(#\s*datocms:start.*#\s*datocms:end|\Z)/m,
32
- "\n\n# datocms:start\n#{content_to_add}\n# datocms:end"
32
+ "\n\n# datocms:start\n#{content_to_add}\n# datocms:end",
33
33
  )
34
34
 
35
- File.open(complete_path, 'w') do |f|
35
+ File.open(complete_path, "w") do |f|
36
36
  f.write new_content
37
37
  end
38
38
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'fileutils'
4
- require 'dato/dump/format'
3
+ require "fileutils"
4
+ require "dato/dump/format"
5
5
 
6
6
  module Dato
7
7
  module Dump
@@ -19,7 +19,7 @@ module Dato
19
19
  def perform
20
20
  FileUtils.mkdir_p(File.dirname(path))
21
21
 
22
- File.open(File.join(context.path, path), 'w') do |file|
22
+ File.open(File.join(context.path, path), "w") do |file|
23
23
  file.write Format.dump(format, value)
24
24
  end
25
25
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'fileutils'
4
- require 'dato/dump/format'
3
+ require "fileutils"
4
+ require "dato/dump/format"
5
5
 
6
6
  module Dato
7
7
  module Dump
@@ -9,8 +9,7 @@ module Dato
9
9
  class CreatePost
10
10
  attr_reader :context, :path
11
11
 
12
- attr_accessor :frontmatter_format, :frontmatter_value
13
- attr_accessor :content
12
+ attr_accessor :frontmatter_format, :frontmatter_value, :content
14
13
 
15
14
  def initialize(context, path)
16
15
  @context = context
@@ -20,10 +19,10 @@ module Dato
20
19
  def perform
21
20
  FileUtils.mkdir_p(File.dirname(path))
22
21
 
23
- File.open(File.join(context.path, path), 'w') do |file|
22
+ File.open(File.join(context.path, path), "w") do |file|
24
23
  file.write Format.frontmatter_dump(
25
24
  frontmatter_format,
26
- frontmatter_value
25
+ frontmatter_value,
27
26
  )
28
27
  file.write "\n\n"
29
28
  file.write content
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'fileutils'
3
+ require "fileutils"
4
4
 
5
5
  module Dato
6
6
  module Dump
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dato/dump/dsl/root'
4
- require 'dato/dump/operation/root'
5
- require 'dato/dump/ssg_detector'
6
- require 'dato/local/loader'
3
+ require "dato/dump/dsl/root"
4
+ require "dato/dump/operation/root"
5
+ require "dato/dump/ssg_detector"
6
+ require "dato/local/loader"
7
7
 
8
8
  module Dato
9
9
  module Dump
@@ -25,7 +25,7 @@ module Dato
25
25
  Dsl::Root.new(
26
26
  File.read(config_path),
27
27
  loader.items_repo,
28
- operation
28
+ operation,
29
29
  )
30
30
 
31
31
  operation.perform
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'toml'
4
- require 'json'
5
- require 'yaml'
3
+ require "toml"
4
+ require "json"
5
+ require "yaml"
6
6
 
7
7
  module Dato
8
8
  module Dump
@@ -18,17 +18,17 @@ module Dato
18
18
 
19
19
  HUGO = [
20
20
  {
21
- file: 'config.toml',
22
- loader: ->(content) { TOML::Parser.new(content).parsed }
21
+ file: "config.toml",
22
+ loader: ->(content) { TOML::Parser.new(content).parsed },
23
23
  },
24
24
  {
25
- file: 'config.yaml',
26
- loader: ->(content) { YAML.safe_load(content) }
25
+ file: "config.yaml",
26
+ loader: ->(content) { YAML.safe_load(content) },
27
27
  },
28
28
  {
29
- file: 'config.json',
30
- loader: ->(content) { JSON.parse(content) }
31
- }
29
+ file: "config.json",
30
+ loader: ->(content) { JSON.parse(content) },
31
+ },
32
32
  ].freeze
33
33
 
34
34
  def initialize(path)
@@ -40,13 +40,13 @@ module Dato
40
40
  node_generator ||
41
41
  python_generator ||
42
42
  hugo ||
43
- 'unknown'
43
+ "unknown"
44
44
  end
45
45
 
46
46
  private
47
47
 
48
48
  def ruby_generator
49
- gemfile_path = File.join(path, 'Gemfile')
49
+ gemfile_path = File.join(path, "Gemfile")
50
50
  return unless File.exist?(gemfile_path)
51
51
 
52
52
  gemfile = File.read(gemfile_path)
@@ -57,13 +57,13 @@ module Dato
57
57
  end
58
58
 
59
59
  def node_generator
60
- package_path = File.join(path, 'package.json')
60
+ package_path = File.join(path, "package.json")
61
61
  return unless File.exist?(package_path)
62
62
 
63
63
  package = JSON.parse(File.read(package_path))
64
64
 
65
- deps = package.fetch('dependencies', {})
66
- dev_deps = package.fetch('devDependencies', {})
65
+ deps = package.fetch("dependencies", {})
66
+ dev_deps = package.fetch("devDependencies", {})
67
67
  all_deps = deps.merge(dev_deps)
68
68
 
69
69
  NODE.find do |generator|
@@ -74,7 +74,7 @@ module Dato
74
74
  end
75
75
 
76
76
  def python_generator
77
- requirements_path = File.join(path, 'requirements.txt')
77
+ requirements_path = File.join(path, "requirements.txt")
78
78
  return unless File.exist?(requirements_path)
79
79
 
80
80
  requirements = File.read(requirements_path)
@@ -89,13 +89,11 @@ module Dato
89
89
  config_path = File.join(path, option[:file])
90
90
  if File.exist?(config_path)
91
91
  config = option[:loader].call(File.read(config_path))
92
- config.key? 'baseurl'
92
+ config.key? "baseurl"
93
93
  end
94
- end && 'hugo'
94
+ end && "hugo"
95
95
  rescue JSON::ParserError
96
96
  nil
97
- rescue Psych::SyntaxError
98
- nil
99
97
  end
100
98
  end
101
99
  end
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
- require 'dato/json_schema_relationships'
2
+
3
+ require "dato/json_schema_relationships"
3
4
 
4
5
  module Dato
5
6
  class JsonApiDeserializer
@@ -28,21 +29,19 @@ module Dato
28
29
 
29
30
  if data[:relationships]
30
31
  relationships.each do |relationship, meta|
31
- if data[:relationships][relationship]
32
- rel_data = data[:relationships][relationship][:data]
33
-
34
- result[relationship] = if meta[:types].length > 1
35
- rel_data
36
- else
37
- if !rel_data
38
- nil
39
- elsif meta[:collection]
40
- rel_data.map { |ref| ref[:id] }
41
- else
42
- rel_data[:id]
43
- end
44
- end
45
- end
32
+ next unless data[:relationships][relationship]
33
+
34
+ rel_data = data[:relationships][relationship][:data]
35
+
36
+ result[relationship] = if meta[:types].length > 1
37
+ rel_data
38
+ elsif !rel_data
39
+ nil
40
+ elsif meta[:collection]
41
+ rel_data.map { |ref| ref[:id] }
42
+ else
43
+ rel_data[:id]
44
+ end
46
45
  end
47
46
  end
48
47