dato 0.7.18 → 0.8.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +42 -5
  3. data/.ruby-version +1 -1
  4. data/.travis.yml +2 -2
  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/account/client.rb +2 -2
  13. data/lib/dato/api_client.rb +37 -43
  14. data/lib/dato/api_error.rb +10 -13
  15. data/lib/dato/cli.rb +18 -18
  16. data/lib/dato/dump/dsl/add_to_data_file.rb +1 -1
  17. data/lib/dato/dump/dsl/create_data_file.rb +1 -1
  18. data/lib/dato/dump/dsl/create_post.rb +1 -1
  19. data/lib/dato/dump/dsl/directory.rb +4 -4
  20. data/lib/dato/dump/dsl/root.rb +7 -7
  21. data/lib/dato/dump/format/json.rb +1 -1
  22. data/lib/dato/dump/format/toml.rb +5 -6
  23. data/lib/dato/dump/format/yaml.rb +2 -3
  24. data/lib/dato/dump/format.rb +3 -3
  25. data/lib/dato/dump/operation/add_to_data_file.rb +4 -4
  26. data/lib/dato/dump/operation/create_data_file.rb +3 -3
  27. data/lib/dato/dump/operation/create_post.rb +5 -6
  28. data/lib/dato/dump/operation/directory.rb +1 -1
  29. data/lib/dato/dump/runner.rb +5 -5
  30. data/lib/dato/dump/ssg_detector.rb +18 -20
  31. data/lib/dato/json_api_deserializer.rb +15 -16
  32. data/lib/dato/json_api_serializer.rb +39 -28
  33. data/lib/dato/json_schema_relationships.rb +19 -23
  34. data/lib/dato/json_schema_type.rb +47 -0
  35. data/lib/dato/local/entities_repo.rb +3 -3
  36. data/lib/dato/local/field_type/color.rb +11 -7
  37. data/lib/dato/local/field_type/file.rb +18 -24
  38. data/lib/dato/local/field_type/gallery.rb +1 -1
  39. data/lib/dato/local/field_type/global_seo.rb +4 -7
  40. data/lib/dato/local/field_type/lat_lon.rb +1 -1
  41. data/lib/dato/local/field_type/seo.rb +1 -1
  42. data/lib/dato/local/field_type/structured_text.rb +63 -0
  43. data/lib/dato/local/field_type/theme.rb +2 -2
  44. data/lib/dato/local/field_type/upload_id.rb +5 -5
  45. data/lib/dato/local/field_type/video.rb +9 -15
  46. data/lib/dato/local/item.rb +11 -12
  47. data/lib/dato/local/items_repo.rb +11 -18
  48. data/lib/dato/local/json_api_entity.rb +4 -3
  49. data/lib/dato/local/loader.rb +30 -31
  50. data/lib/dato/local/site.rb +3 -4
  51. data/lib/dato/paginator.rb +4 -4
  52. data/lib/dato/repo.rb +23 -30
  53. data/lib/dato/site/client.rb +5 -5
  54. data/lib/dato/upload/create_upload_path.rb +7 -10
  55. data/lib/dato/upload/file.rb +3 -3
  56. data/lib/dato/upload/image.rb +1 -1
  57. data/lib/dato/utils/build_modular_block.rb +4 -4
  58. data/lib/dato/utils/favicon_tags_builder.rb +10 -10
  59. data/lib/dato/utils/locale_value.rb +1 -1
  60. data/lib/dato/utils/meta_tags/article_modified_time.rb +3 -3
  61. data/lib/dato/utils/meta_tags/article_publisher.rb +2 -2
  62. data/lib/dato/utils/meta_tags/base.rb +5 -6
  63. data/lib/dato/utils/meta_tags/description.rb +4 -4
  64. data/lib/dato/utils/meta_tags/image.rb +4 -5
  65. data/lib/dato/utils/meta_tags/og_locale.rb +2 -2
  66. data/lib/dato/utils/meta_tags/og_site_name.rb +2 -2
  67. data/lib/dato/utils/meta_tags/og_type.rb +3 -3
  68. data/lib/dato/utils/meta_tags/robots.rb +2 -2
  69. data/lib/dato/utils/meta_tags/title.rb +6 -6
  70. data/lib/dato/utils/meta_tags/twitter_card.rb +2 -2
  71. data/lib/dato/utils/meta_tags/twitter_site.rb +2 -2
  72. data/lib/dato/utils/seo_tags_builder.rb +12 -12
  73. data/lib/dato/version.rb +1 -1
  74. data/lib/dato.rb +11 -9
  75. metadata +10 -8
@@ -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
 
@@ -1,13 +1,15 @@
1
1
  # frozen_string_literal: true
2
- require 'dato/json_schema_relationships'
2
+
3
+ require "dato/json_schema_relationships"
4
+ require "dato/json_schema_type"
3
5
 
4
6
  module Dato
5
7
  class JsonApiSerializer
6
8
  attr_reader :link, :type
7
9
 
8
- def initialize(type, link)
10
+ def initialize(type: nil, link: nil)
9
11
  @link = link
10
- @type = type
12
+ @type = type || type_from_schema
11
13
  end
12
14
 
13
15
  def serialize(resource, id = nil)
@@ -16,19 +18,22 @@ module Dato
16
18
 
17
19
  data[:id] = id || resource[:id] if id || resource[:id]
18
20
 
19
- if resource.has_key?(:meta)
20
- resource.delete(:meta)
21
- end
21
+ resource.delete(:meta) if resource.key?(:meta)
22
22
 
23
23
  data[:type] = type
24
- data[:attributes] = serialized_attributes(resource)
25
24
 
26
- serialized_relationships = serialized_relationships(resource)
25
+ if link.schema &&
26
+ link.schema.properties["data"] &&
27
+ link.schema.properties["data"].properties.keys.include?("attributes")
27
28
 
28
- if serialized_relationships
29
- data[:relationships] = serialized_relationships
29
+ serialized_resource_attributes = serialized_attributes(resource)
30
+ data[:attributes] = serialized_resource_attributes
30
31
  end
31
32
 
33
+ serialized_relationships = serialized_relationships(resource)
34
+
35
+ data[:relationships] = serialized_relationships if serialized_relationships
36
+
32
37
  { data: data }
33
38
  end
34
39
 
@@ -61,18 +66,18 @@ module Dato
61
66
  value.symbolize_keys
62
67
  end
63
68
  else
64
- type = meta[:types].first
69
+ meta_type = meta[:types].first
65
70
  if meta[:collection]
66
71
  value.map do |id|
67
72
  {
68
- type: type,
69
- id: id.to_s
73
+ type: meta_type,
74
+ id: id.to_s,
70
75
  }
71
76
  end
72
77
  else
73
78
  {
74
- type: type,
75
- id: value.to_s
79
+ type: meta_type,
80
+ id: value.to_s,
76
81
  }
77
82
  end
78
83
  end
@@ -88,21 +93,23 @@ module Dato
88
93
  end
89
94
 
90
95
  def attributes(resource)
91
- if type == 'item'
92
- return resource.keys.map(&:to_sym) - %i[
93
- item_type
94
- id
95
- created_at
96
- updated_at
97
- creator
98
- ]
96
+ if type == "item"
97
+ return resource.keys.reject do |key|
98
+ %i[
99
+ item_type
100
+ id
101
+ created_at
102
+ updated_at
103
+ creator
104
+ ].include?(key.to_sym)
105
+ end
99
106
  end
100
107
 
101
- link_attributes['properties'].keys.map(&:to_sym)
108
+ link_attributes["properties"].keys.map(&:to_sym)
102
109
  end
103
110
 
104
111
  def required_attributes
105
- return [] if type == 'item'
112
+ return [] if type == "item"
106
113
 
107
114
  (link_attributes.required || []).map(&:to_sym)
108
115
  end
@@ -112,7 +119,7 @@ module Dato
112
119
  end
113
120
 
114
121
  def required_relationships
115
- if link.schema.properties['data'].required.include?("relationships")
122
+ if link.schema.properties["data"].required.include?("relationships")
116
123
  (link_relationships.required || []).map(&:to_sym)
117
124
  else
118
125
  []
@@ -120,11 +127,15 @@ module Dato
120
127
  end
121
128
 
122
129
  def link_attributes
123
- link.schema.properties['data'].properties['attributes']
130
+ link.schema.properties["data"].properties["attributes"]
124
131
  end
125
132
 
126
133
  def link_relationships
127
- link.schema.properties['data'].properties['relationships']
134
+ link.schema.properties["data"].properties["relationships"]
135
+ end
136
+
137
+ def type_from_schema
138
+ Dato::JsonSchemaType.new(link.schema).call
128
139
  end
129
140
  end
130
141
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Dato
2
4
  class JsonSchemaRelationships
3
5
  attr_reader :schema
@@ -7,46 +9,40 @@ module Dato
7
9
  end
8
10
 
9
11
  def relationships
10
- if !schema || !schema.properties['data']
11
- return {}
12
- end
12
+ return {} if !schema || !schema.properties["data"]
13
13
 
14
- entity = if schema.properties['data'].type.first == 'array'
15
- schema.properties['data'].items
14
+ entity = if schema.properties["data"].type.first == "array"
15
+ schema.properties["data"].items
16
16
  else
17
- schema.properties['data']
17
+ schema.properties["data"]
18
18
  end
19
19
 
20
- if !entity || !entity.properties['relationships'] || !entity.properties['relationships']
21
- return {}
22
- end
20
+ return {} if !entity || !entity.properties["relationships"] || !entity.properties["relationships"]
23
21
 
24
- relationships = entity.properties['relationships'].properties
22
+ relationships = entity.properties["relationships"].properties
25
23
 
26
24
  relationships.each_with_object({}) do |(relationship, schema), acc|
27
- is_collection = schema.properties['data'].type.first == 'array'
25
+ is_collection = schema.properties["data"].type.first == "array"
28
26
 
29
27
  types = if is_collection
30
- [type(schema.properties['data'].items)]
31
- elsif schema.properties['data'].type.first == 'object'
32
- [type(schema.properties['data'])]
33
- else
34
- schema.properties['data'].any_of.map do |option|
35
- type(option)
36
- end.compact
37
- end
28
+ [type(schema.properties["data"].items)]
29
+ elsif schema.properties["data"].type.first == "object"
30
+ [type(schema.properties["data"])]
31
+ else
32
+ schema.properties["data"].any_of.map do |option|
33
+ type(option)
34
+ end.compact
35
+ end
38
36
 
39
37
  acc[relationship.to_sym] = {
40
38
  collection: is_collection,
41
- types: types
39
+ types: types,
42
40
  }
43
41
  end
44
42
  end
45
43
 
46
44
  def type(definition)
47
- if definition.properties['type']
48
- definition.properties['type'].pattern.source.gsub(/(^\^|\$$)/, '')
49
- end
45
+ definition.properties["type"].pattern.source.gsub(/(^\^|\$$)/, "") if definition.properties["type"]
50
46
  end
51
47
  end
52
48
  end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dato
4
+ class JsonSchemaType
5
+ attr_reader :schema
6
+
7
+ def initialize(schema)
8
+ @schema = schema
9
+ end
10
+
11
+ def call
12
+ type_property = find_info_for_type_property
13
+
14
+ return nil unless type_property
15
+
16
+ type_property.pattern.to_s.gsub(/(^(\(\?-mix:\^)|(\$\))$)/, "")
17
+ end
18
+
19
+ private
20
+
21
+ def find_info_for_type_property
22
+ entity = find_entity_in_data
23
+
24
+ return nil unless entity
25
+
26
+ entity.properties["type"]
27
+ end
28
+
29
+ def find_entity_in_data
30
+ return nil if !schema || !schema.properties["data"]
31
+
32
+ if schema.properties["data"].type.first == "array"
33
+ return schema.properties["data"].items if schema.properties["data"].items
34
+
35
+ return nil
36
+ end
37
+
38
+ return schema.properties["data"] if schema.properties["data"].type.first == "object"
39
+
40
+ if schema.properties["data"].any_of
41
+ return schema.properties["data"].any_of.reject { |x| x.definitions.type.example == "job" }
42
+ end
43
+
44
+ nil
45
+ end
46
+ end
47
+ end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dato/local/json_api_entity'
3
+ require "dato/local/json_api_entity"
4
4
 
5
5
  module Dato
6
6
  module Local
@@ -27,8 +27,8 @@ module Dato
27
27
  end
28
28
 
29
29
  def destroy_item_type(id)
30
- entities.fetch('item', {}).delete_if { |_item_id, item| item.item_type.id == id }
31
- entities.fetch('item_type', {}).delete(id)
30
+ entities.fetch("item", {}).delete_if { |_item_id, item| item.item_type.id == id }
31
+ entities.fetch("item_type", {}).delete(id)
32
32
  end
33
33
 
34
34
  def upsert_entities(*payloads)
@@ -4,14 +4,14 @@ module Dato
4
4
  module Local
5
5
  module FieldType
6
6
  class Color
7
- attr_reader :red, :green, :blue, :alpha
7
+ attr_reader :red, :green, :blue
8
8
 
9
9
  def self.parse(value, _repo)
10
10
  value && new(
11
11
  value[:red],
12
12
  value[:green],
13
13
  value[:blue],
14
- value[:alpha]
14
+ value[:alpha],
15
15
  )
16
16
  end
17
17
 
@@ -19,17 +19,21 @@ module Dato
19
19
  @red = red
20
20
  @green = green
21
21
  @blue = blue
22
- @alpha = alpha / 255.0
22
+ @alpha = alpha
23
23
  end
24
24
 
25
25
  def rgb
26
- if alpha == 1.0
26
+ if @alpha == 255
27
27
  "rgb(#{red}, #{green}, #{blue})"
28
28
  else
29
29
  "rgba(#{red}, #{green}, #{blue}, #{alpha})"
30
30
  end
31
31
  end
32
32
 
33
+ def alpha
34
+ @alpha / 255.0
35
+ end
36
+
33
37
  def hex
34
38
  r = red.to_s(16)
35
39
  g = green.to_s(16)
@@ -41,9 +45,9 @@ module Dato
41
45
  b = "0#{b}" if b.length == 1
42
46
  a = "0#{a}" if a.length == 1
43
47
 
44
- hex = '#' + r + g + b
48
+ hex = "##{r}#{g}#{b}"
45
49
 
46
- hex += a if a != 'ff'
50
+ hex += a if a != "ff"
47
51
 
48
52
  hex
49
53
  end
@@ -54,7 +58,7 @@ module Dato
54
58
  green: green,
55
59
  blue: blue,
56
60
  rgb: rgb,
57
- hex: hex
61
+ hex: hex,
58
62
  }
59
63
  end
60
64
  end