easol-canvas 1.5.0 → 2.0.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c61a6785fbf34da110e1fe2b01a9f096ff4aaf8ea3cfbef780491b5e94e68998
4
- data.tar.gz: 3acb2a3215a5fd874ad5e54cc719204cb0a4698218935f2546ce5cacf3f73777
3
+ metadata.gz: 5446d70b87d779a13b4a5b3f132b91a29722d84167fcc2ac9b61a142e7b5a45c
4
+ data.tar.gz: ccc2f5bc197c2f7ec72969289989742f3400f69e2a2eb468c001fd994237f2bc
5
5
  SHA512:
6
- metadata.gz: 660512a56bea758cae95483fdaefd41a75156a7c15723e661749a64feb6dbc847bab31e279fecd733af807c33491a138b9c4afc850bfd2db84e8b1ae5d3c848a
7
- data.tar.gz: 75fdbbefd7cfccc1849bf26e1c42e9f24f274c1d1ed27774d6b1a5085a5caafd30b4b8a0499d418686320157b6335116e0a25bf973b24fedee60210bb64c8d0d
6
+ metadata.gz: a1b2ab985beac4aef8812c35fcda2707c52fc204c26435d7bf9dd7b33441dc9666739e4a9319e64e1fab31fab8f46d73e7af79c63b14ae21a084f517c0e7f9ea
7
+ data.tar.gz: f57a9566ebb142092e574dc0889a636c673342e5a71e5ccc1f111951c4ac1fa78995dbbe090cd2de7d5c3cd073dbecd3999aca06889a3beb5419d72616547090
@@ -22,8 +22,9 @@ module Canvas
22
22
  def run
23
23
  custom_types = Canvas::FetchCustomTypes.call
24
24
  block_files.each do |filename|
25
- file = File.read(filename)
26
- front_matter = extract_front_matter(file)
25
+ front_matter = extract_front_matter(filename)
26
+ next unless front_matter
27
+
27
28
  validate_format(filename, front_matter) &&
28
29
  validate_schema(filename, front_matter, custom_types)
29
30
  end
@@ -57,10 +58,18 @@ module Canvas
57
58
  end
58
59
  end
59
60
 
60
- def extract_front_matter(file)
61
+ def extract_front_matter(filename)
62
+ file = File.read(filename)
63
+
61
64
  extractor = Canvas::FrontMatterExtractor.new(file)
62
65
  front_matter = extractor.front_matter
63
66
  front_matter.nil? ? {} : YAML.safe_load(front_matter)
67
+ rescue Psych::SyntaxError
68
+ @offenses << Offense.new(
69
+ message: "Invalid Block Schema: #{filename} - \nFront matter's YAML is not in a valid format"
70
+ )
71
+
72
+ nil
64
73
  end
65
74
  end
66
75
  end
@@ -51,8 +51,7 @@ module Canvas
51
51
  front_matter["attributes"].values.all? { |attr| attr.is_a?(Hash) }
52
52
  end
53
53
 
54
- def validate_schema(front_matter)
55
- schema = extract_schema(front_matter)
54
+ def validate_schema(schema)
56
55
  validator = Validator::FooterSchema.new(
57
56
  schema: schema,
58
57
  custom_types: Canvas::FetchCustomTypes.call
@@ -71,11 +70,5 @@ module Canvas
71
70
  front_matter = extractor.front_matter
72
71
  front_matter.nil? ? {} : YAML.safe_load(front_matter)
73
72
  end
74
-
75
- def extract_schema(front_matter)
76
- front_matter.merge(
77
- "attributes" => Canvas::ExpandAttributes.call(front_matter["attributes"])
78
- )
79
- end
80
73
  end
81
74
  end
@@ -51,8 +51,7 @@ module Canvas
51
51
  front_matter["attributes"].values.all? { |attr| attr.is_a?(Hash) }
52
52
  end
53
53
 
54
- def validate_schema(front_matter)
55
- schema = extract_schema(front_matter)
54
+ def validate_schema(schema)
56
55
  validator = Validator::MenuSchema.new(
57
56
  schema: schema,
58
57
  custom_types: Canvas::FetchCustomTypes.call
@@ -71,11 +70,5 @@ module Canvas
71
70
  front_matter = extractor.front_matter
72
71
  front_matter.nil? ? {} : YAML.safe_load(front_matter)
73
72
  end
74
-
75
- def extract_schema(front_matter)
76
- front_matter.merge(
77
- "attributes" => Canvas::ExpandAttributes.call(front_matter["attributes"])
78
- )
79
- end
80
73
  end
81
74
  end
@@ -9,17 +9,25 @@ module Canvas
9
9
  # This class is used to validate a schema for a block.
10
10
  # Example of a valid block schema:
11
11
  # {
12
- # "attributes" => [
13
- # {
14
- # "name" => "my_title",
12
+ # "attributes" => {
13
+ # "my_title" => {
15
14
  # "type" => "string"
16
15
  # },
17
- # {
18
- # "name" => "my_color",
16
+ # "my_color" => {
19
17
  # "type" => "color",
20
18
  # "label" => "My color",
21
19
  # "hint" => "Select your favourite color"
22
20
  # }
21
+ # },
22
+ # "layout" => [
23
+ # {
24
+ # "type" => "tab",
25
+ # "label" => "Content",
26
+ # "elements" => [
27
+ # "my_title",
28
+ # "my_color"
29
+ # ]
30
+ # }
23
31
  # ]
24
32
  # }
25
33
  class BlockSchema
@@ -51,7 +59,7 @@ module Canvas
51
59
 
52
60
  def ensure_valid_format
53
61
  return true if schema.is_a?(Hash) &&
54
- (schema["attributes"].nil? || attributes_array_of_hashes?(schema))
62
+ (schema["attributes"].nil? || attributes_hash_of_hashes?(schema))
55
63
 
56
64
  @errors << "Schema is not in a valid format"
57
65
  false
@@ -78,7 +86,8 @@ module Canvas
78
86
  def ensure_attributes_are_valid
79
87
  return true unless schema["attributes"]
80
88
 
81
- schema["attributes"].each do |attribute_schema|
89
+ attributes = Canvas::ExpandAttributes.call(schema["attributes"])
90
+ attributes.each do |attribute_schema|
82
91
  attr_validator = Validator::SchemaAttribute.new(
83
92
  attribute: attribute_schema,
84
93
  custom_types: @custom_types
@@ -90,22 +99,17 @@ module Canvas
90
99
  end
91
100
  end
92
101
 
93
- def attributes_array_of_hashes?(schema)
94
- schema["attributes"].is_a?(Array) &&
95
- schema["attributes"].all? { |attr| attr.is_a?(Hash) }
102
+ def attributes_hash_of_hashes?(schema)
103
+ schema["attributes"].is_a?(Hash) &&
104
+ schema["attributes"].values.all? { |attr| attr.is_a?(Hash) }
96
105
  end
97
106
 
107
+ # To support older schemas that do not nest the attributes
108
+ # under the `attributes` key.
98
109
  def normalize_schema(schema)
99
- if schema.key?("attributes")
100
- {
101
- **schema,
102
- "attributes" => Canvas::ExpandAttributes.call(schema["attributes"])
103
- }
104
- else
105
- {
106
- "attributes" => Canvas::ExpandAttributes.call(schema)
107
- }
108
- end
110
+ return schema if schema.key?("attributes")
111
+
112
+ { "attributes" => schema }
109
113
  end
110
114
  end
111
115
  end
@@ -11,19 +11,27 @@ module Canvas
11
11
  #
12
12
  # Example:
13
13
  # {
14
- # "max_item_levels": 2,
15
- # "supports_open_new_tab": "true",
16
- # "attributes": {
17
- # "fixed": {
18
- # "group": "design",
19
- # "label": "Fixed when scrolling",
20
- # "hint": "The menu will stay fixed to the top when scrolling down the page.",
21
- # "type": "boolean",
22
- # "default: "false"
14
+ # "max_item_levels" => 2,
15
+ # "supports_open_new_tab" => "true",
16
+ # "attributes" => {
17
+ # "text_color" => {
18
+ # "type" => "color"
19
+ # },
20
+ # "background_color" => {
21
+ # "type" => "color"
23
22
  # }
24
- # }
23
+ # },
24
+ # "layout" => [
25
+ # {
26
+ # "type" => "tab",
27
+ # "label" => "Content",
28
+ # "elements" => [
29
+ # "text_color",
30
+ # "background_color"
31
+ # ]
32
+ # }
33
+ # ]
25
34
  # }
26
- #
27
35
  class FooterSchema < MenuSchema; end
28
36
  end
29
37
  end
@@ -9,13 +9,12 @@ module Canvas
9
9
  # This class is used to validate a layout definition, part of block schema.
10
10
  # Example of a valid layout definition:
11
11
  # {
12
- # "attributes" => [
13
- # {
14
- # "name" => "title",
12
+ # "attributes" => {
13
+ # "title" => {
15
14
  # "type" => "string"
16
15
  # }
17
16
  # ...
18
- # ],
17
+ # },
19
18
  # "layout" => [
20
19
  # {
21
20
  # "label" => "Design",
@@ -83,7 +82,7 @@ module Canvas
83
82
 
84
83
  def ensure_no_unrecognized_keys
85
84
  attributes = fetch_all_attribute_names
86
- defined_attributes = schema["attributes"]&.map { |definition| normalize_attribute(definition["name"]) } || []
85
+ defined_attributes = expanded_attributes.map { |definition| normalize_attribute(definition["name"]) } || []
87
86
 
88
87
  attributes.each do |attribute, location|
89
88
  @errors << "Unrecognized attribute `#{attribute}`. Location: #{location}" unless defined_attributes.include?(attribute)
@@ -144,13 +143,13 @@ module Canvas
144
143
  def ensure_accordion_toggles_are_valid
145
144
  accordion_toggles = fetch_elements_of_type("accordion_toggle")
146
145
  accordion_toggles.each do |accordion_toggle, location|
147
- toggle_attribute = schema["attributes"]&.detect { |attr|
146
+ toggle_attribute = expanded_attributes.detect { |attr|
148
147
  attr["name"] == accordion_toggle["toggle_attribute"]
149
148
  }
150
149
 
151
150
  if toggle_attribute.nil?
152
151
  @errors << "The toggle_attribute in accordion_toggle is unrecognized. Location: #{location}"
153
- elsif toggle_attribute["type"] != "boolean"
152
+ elsif toggle_attribute["type"]&.downcase != "boolean"
154
153
  @errors << "The toggle_attribute in accordion_toggle must be a boolean. Location: #{location}"
155
154
  end
156
155
  end
@@ -162,13 +161,19 @@ module Canvas
162
161
 
163
162
  def schema_definition
164
163
  File.read(
165
- File.join(File.dirname(__FILE__), "../../../", "schema_definitions", "block_layout.json")
164
+ File.join(File.dirname(__FILE__), "../../../", "schema_definitions", "layout.json")
166
165
  )
167
166
  end
168
167
 
169
168
  def normalize_attribute(name)
170
169
  name.strip.downcase
171
170
  end
171
+
172
+ def expanded_attributes
173
+ return [] if schema["attributes"].nil?
174
+
175
+ @_expanded_attributes ||= Canvas::ExpandAttributes.call(schema["attributes"])
176
+ end
172
177
  end
173
178
  end
174
179
  end
@@ -7,21 +7,33 @@ module Canvas
7
7
  #
8
8
  # Example:
9
9
  # {
10
- # "max_item_levels": 2,
11
- # "supports_open_new_tab": "true",
12
- # "attributes": {
13
- # "fixed": {
14
- # "group": "design",
15
- # "label": "Fixed when scrolling",
16
- # "hint": "The menu will stay fixed to the top when scrolling down the page.",
17
- # "type": "boolean",
18
- # "default: "false"
10
+ # "max_item_levels" => 2,
11
+ # "supports_open_new_tab" => "true",
12
+ # "attributes" => {
13
+ # "fixed" => {
14
+ # "group" => "design",
15
+ # "label" => "Fixed when scrolling",
16
+ # "hint" => "The menu will stay fixed to the top when scrolling down the page.",
17
+ # "type" => "boolean",
18
+ # "default" => "false"
19
+ # },
20
+ # "background_color" => {
21
+ # "type" => "color"
19
22
  # }
20
- # }
23
+ # },
24
+ # "layout" => [
25
+ # {
26
+ # "type" => "tab",
27
+ # "label" => "Content",
28
+ # "elements" => [
29
+ # "fixed",
30
+ # "background_color"
31
+ # ]
32
+ # }
33
+ # ]
21
34
  # }
22
- #
23
35
  class MenuSchema
24
- PERMITTED_KEYS = %w[max_item_levels supports_open_new_tab attributes].freeze
36
+ PERMITTED_KEYS = %w[max_item_levels supports_open_new_tab attributes layout].freeze
25
37
  ADDITIONAL_RESERVED_NAMES = %w[items type].freeze
26
38
 
27
39
  attr_reader :schema, :errors
@@ -38,6 +50,7 @@ module Canvas
38
50
  if ensure_valid_format
39
51
  ensure_no_unrecognized_keys
40
52
  ensure_max_item_levels_is_valid
53
+ ensure_layout_is_valid
41
54
  ensure_attributes_are_valid
42
55
  end
43
56
 
@@ -48,7 +61,7 @@ module Canvas
48
61
 
49
62
  def ensure_valid_format
50
63
  return true if schema.is_a?(Hash) &&
51
- (schema["attributes"].nil? || attributes_array_of_hashes?(schema))
64
+ (schema["attributes"].nil? || attributes_hash_of_hashes?(schema))
52
65
 
53
66
  @errors << "Schema is not in a valid format"
54
67
  false
@@ -70,10 +83,21 @@ module Canvas
70
83
  false
71
84
  end
72
85
 
86
+ def ensure_layout_is_valid
87
+ return true unless schema["layout"]
88
+
89
+ layout_validator = LayoutSchema.new(schema: @schema)
90
+ return true if layout_validator.validate
91
+
92
+ @errors += layout_validator.errors
93
+ false
94
+ end
95
+
73
96
  def ensure_attributes_are_valid
74
97
  return true unless schema["attributes"]
75
98
 
76
- schema["attributes"].each do |attribute_schema|
99
+ attributes = Canvas::ExpandAttributes.call(schema["attributes"])
100
+ attributes.each do |attribute_schema|
77
101
  attr_validator = Validator::SchemaAttribute.new(
78
102
  attribute: attribute_schema,
79
103
  custom_types: @custom_types,
@@ -86,9 +110,9 @@ module Canvas
86
110
  end
87
111
  end
88
112
 
89
- def attributes_array_of_hashes?(schema)
90
- schema["attributes"].is_a?(Array) &&
91
- schema["attributes"].all? { |attr| attr.is_a?(Hash) }
113
+ def attributes_hash_of_hashes?(schema)
114
+ schema["attributes"].is_a?(Hash) &&
115
+ schema["attributes"].values.all? { |attr| attr.is_a?(Hash) }
92
116
  end
93
117
  end
94
118
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Canvas
4
- VERSION = "1.5.0"
4
+ VERSION = "2.0.0"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: easol-canvas
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kyle Byrne
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2022-07-21 00:00:00.000000000 Z
12
+ date: 2022-07-27 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: thor
@@ -150,7 +150,7 @@ files:
150
150
  - lib/canvas/validators/schema_attributes/variant.rb
151
151
  - lib/canvas/version.rb
152
152
  - lib/easol/canvas.rb
153
- - schema_definitions/block_layout.json
153
+ - schema_definitions/layout.json
154
154
  homepage: https://rubygems.org/gems/easol-canvas
155
155
  licenses:
156
156
  - MIT