easol-canvas 1.4.1 → 2.1.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 +4 -4
- data/lib/canvas/checks/valid_block_schemas_check.rb +12 -3
- data/lib/canvas/checks/valid_footer_schema_check.rb +1 -8
- data/lib/canvas/checks/valid_menu_schema_check.rb +1 -8
- data/lib/canvas/validators/block_schema.rb +24 -20
- data/lib/canvas/validators/footer_schema.rb +19 -11
- data/lib/canvas/validators/layout_schema.rb +103 -31
- data/lib/canvas/validators/menu_schema.rb +41 -17
- data/lib/canvas/version.rb +1 -1
- data/schema_definitions/{block_layout.json → layout.json} +23 -3
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b20a9e978f946b59d3d3c9e2ee0b6763948c59278cc839bff63931879e3f18bb
|
4
|
+
data.tar.gz: 4dc2f01cbc06e1d60c99fd72211442bddfae47011cae0f237bec5eea12f2dddc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4ce1b8bab498d701f7ba028879060c7113ae231e59c9eeb2f1efb5d8ec6930043aeb1e6b061a5b121fa7f89ae470520482f8d2521aac7de606c3f2ef45be093e
|
7
|
+
data.tar.gz: cb1d28f8904587f6061ff31914f167cc055bc6bd95eb96f8acd8ff40550e5e2673f4d2386a12cf554f4976d8a5f425453a8e3e9c9ab24260ba05cbdbf93e6c5e
|
@@ -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
|
-
|
26
|
-
|
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(
|
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(
|
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(
|
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? ||
|
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"]
|
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
|
94
|
-
schema["attributes"].is_a?(
|
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
|
-
|
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"
|
15
|
-
# "supports_open_new_tab"
|
16
|
-
# "attributes"
|
17
|
-
# "
|
18
|
-
#
|
19
|
-
#
|
20
|
-
#
|
21
|
-
#
|
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,23 +9,38 @@ 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
|
+
# "title" => {
|
14
|
+
# "type" => "string"
|
15
|
+
# }
|
16
|
+
# ...
|
17
|
+
# },
|
12
18
|
# "layout" => [
|
13
|
-
#
|
14
|
-
#
|
15
|
-
#
|
16
|
-
# "elements" => [
|
17
|
-
# "heading",
|
18
|
-
# {
|
19
|
-
# "type" => "accordion",
|
20
|
-
# "label" => "Logo",
|
19
|
+
# {
|
20
|
+
# "label" => "Design",
|
21
|
+
# "type" => "tab",
|
21
22
|
# "elements" => [
|
22
|
-
#
|
23
|
-
#
|
24
|
-
# "
|
25
|
-
#
|
26
|
-
#
|
27
|
-
#
|
28
|
-
#
|
23
|
+
# "heading",
|
24
|
+
# {
|
25
|
+
# "type" => "accordion",
|
26
|
+
# "label" => "Logo",
|
27
|
+
# "elements" => [
|
28
|
+
# "description",
|
29
|
+
# { "type" => "attribute", "name" => "logo_alt" },
|
30
|
+
# "title"
|
31
|
+
# ]
|
32
|
+
# },
|
33
|
+
# {
|
34
|
+
# "type" => "accordion_toggle",
|
35
|
+
# "toggle_attribute" => "cta_enabled",
|
36
|
+
# "elements" => [
|
37
|
+
# "cta_text",
|
38
|
+
# "cta_target"
|
39
|
+
# ]
|
40
|
+
# }
|
41
|
+
# ]
|
42
|
+
# }
|
43
|
+
# ]
|
29
44
|
# }
|
30
45
|
class LayoutSchema
|
31
46
|
attr_reader :errors
|
@@ -41,6 +56,8 @@ module Canvas
|
|
41
56
|
if ensure_valid_format
|
42
57
|
ensure_no_unrecognized_keys
|
43
58
|
ensure_no_duplicate_keys
|
59
|
+
ensure_accordion_toggles_are_valid
|
60
|
+
ensure_unique_tabs
|
44
61
|
end
|
45
62
|
|
46
63
|
@errors.empty?
|
@@ -48,8 +65,25 @@ module Canvas
|
|
48
65
|
|
49
66
|
private
|
50
67
|
|
68
|
+
attr_reader :schema
|
69
|
+
|
70
|
+
def ensure_unique_tabs
|
71
|
+
tabs = fetch_elements_of_type("tab")
|
72
|
+
duplicates =
|
73
|
+
tabs
|
74
|
+
.map { |item| [item[0]["label"], item[1]] }
|
75
|
+
.group_by { |(key, _)| key }
|
76
|
+
.filter { |key, usage| usage.size > 1 }
|
77
|
+
|
78
|
+
unless duplicates.empty?
|
79
|
+
duplicates.each do |tab, usage|
|
80
|
+
@errors << "Duplicated tab label `#{tab}` found. Location: #{usage.map { |(_, location)| location }.join(", ")}"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
51
85
|
def ensure_no_duplicate_keys
|
52
|
-
attributes =
|
86
|
+
attributes = fetch_all_attribute_names
|
53
87
|
duplicates =
|
54
88
|
attributes
|
55
89
|
.group_by { |(key)| key }
|
@@ -63,37 +97,54 @@ module Canvas
|
|
63
97
|
end
|
64
98
|
|
65
99
|
def ensure_no_unrecognized_keys
|
66
|
-
attributes =
|
67
|
-
defined_attributes =
|
100
|
+
attributes = fetch_all_attribute_names
|
101
|
+
defined_attributes = expanded_attributes.map { |definition| normalize_attribute(definition["name"]) } || []
|
68
102
|
|
69
103
|
attributes.each do |attribute, location|
|
70
104
|
@errors << "Unrecognized attribute `#{attribute}`. Location: #{location}" unless defined_attributes.include?(attribute)
|
71
105
|
end
|
72
106
|
end
|
73
107
|
|
74
|
-
|
75
|
-
|
108
|
+
# @return [Array<Array(String, String)>] an array of all the attribute names that
|
109
|
+
# are mentioned in the layout schema, along with its path. The names are
|
110
|
+
# normalized, i.e. downcased.
|
111
|
+
def fetch_all_attribute_names
|
112
|
+
attributes = fetch_elements_of_type("attribute")
|
113
|
+
attributes.map do |(node, path)|
|
114
|
+
[
|
115
|
+
normalize_attribute(node.is_a?(Hash) ? node["name"] : node),
|
116
|
+
path
|
117
|
+
]
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
# @param type [String] the element type to fetch
|
122
|
+
# @return [Array<Array(<Hash, String>, String)] an array of elements that match
|
123
|
+
# the given type. Each element is an array containing the node and its path.
|
124
|
+
def fetch_elements_of_type(type)
|
125
|
+
elements = []
|
126
|
+
|
127
|
+
fetch_element = ->(node, path) {
|
128
|
+
if type == "attribute" && node.is_a?(String)
|
129
|
+
elements << [node, path]
|
130
|
+
elsif node["type"] == type
|
131
|
+
elements << [node, path]
|
132
|
+
end
|
76
133
|
|
77
|
-
fetch_attribute_type = ->(node, path) {
|
78
134
|
if node.is_a?(Hash) && node.key?("elements")
|
79
135
|
node["elements"].each_with_index do |element, i|
|
80
136
|
current_path = "#{path}/elements/#{i}"
|
81
|
-
|
137
|
+
fetch_element.call(element, current_path)
|
82
138
|
end
|
83
|
-
else
|
84
|
-
attribute_keys << [
|
85
|
-
normalize_attribute(node.is_a?(Hash) ? node["name"] : node),
|
86
|
-
path
|
87
|
-
]
|
88
139
|
end
|
89
140
|
}
|
90
141
|
|
91
142
|
layout_schema.each_with_index do |tab, i|
|
92
143
|
current_path = "layout/#{i}"
|
93
|
-
|
144
|
+
fetch_element.call(tab, current_path)
|
94
145
|
end
|
95
146
|
|
96
|
-
|
147
|
+
elements
|
97
148
|
end
|
98
149
|
|
99
150
|
def ensure_valid_format
|
@@ -105,19 +156,40 @@ module Canvas
|
|
105
156
|
false
|
106
157
|
end
|
107
158
|
|
159
|
+
def ensure_accordion_toggles_are_valid
|
160
|
+
accordion_toggles = fetch_elements_of_type("accordion_toggle")
|
161
|
+
accordion_toggles.each do |accordion_toggle, location|
|
162
|
+
toggle_attribute = expanded_attributes.detect { |attr|
|
163
|
+
attr["name"] == accordion_toggle["toggle_attribute"]
|
164
|
+
}
|
165
|
+
|
166
|
+
if toggle_attribute.nil?
|
167
|
+
@errors << "The toggle_attribute in accordion_toggle is unrecognized. Location: #{location}"
|
168
|
+
elsif toggle_attribute["type"]&.downcase != "boolean"
|
169
|
+
@errors << "The toggle_attribute in accordion_toggle must be a boolean. Location: #{location}"
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
108
174
|
def layout_schema
|
109
|
-
|
175
|
+
schema["layout"] || []
|
110
176
|
end
|
111
177
|
|
112
178
|
def schema_definition
|
113
179
|
File.read(
|
114
|
-
File.join(File.dirname(__FILE__), "../../../", "schema_definitions", "
|
180
|
+
File.join(File.dirname(__FILE__), "../../../", "schema_definitions", "layout.json")
|
115
181
|
)
|
116
182
|
end
|
117
183
|
|
118
184
|
def normalize_attribute(name)
|
119
185
|
name.strip.downcase
|
120
186
|
end
|
187
|
+
|
188
|
+
def expanded_attributes
|
189
|
+
return [] if schema["attributes"].nil?
|
190
|
+
|
191
|
+
@_expanded_attributes ||= Canvas::ExpandAttributes.call(schema["attributes"])
|
192
|
+
end
|
121
193
|
end
|
122
194
|
end
|
123
195
|
end
|
@@ -7,21 +7,33 @@ module Canvas
|
|
7
7
|
#
|
8
8
|
# Example:
|
9
9
|
# {
|
10
|
-
# "max_item_levels"
|
11
|
-
# "supports_open_new_tab"
|
12
|
-
# "attributes"
|
13
|
-
# "fixed"
|
14
|
-
# "group"
|
15
|
-
# "label"
|
16
|
-
# "hint"
|
17
|
-
# "type"
|
18
|
-
# "default
|
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? ||
|
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"]
|
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
|
90
|
-
schema["attributes"].is_a?(
|
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
|
data/lib/canvas/version.rb
CHANGED
@@ -24,20 +24,21 @@
|
|
24
24
|
"items": {
|
25
25
|
"oneOf": [
|
26
26
|
{ "type": "string" },
|
27
|
-
{ "$ref": "#/$defs/
|
27
|
+
{ "$ref": "#/$defs/accordion" },
|
28
|
+
{ "$ref": "#/$defs/accordion_toggle" },
|
28
29
|
{ "$ref": "#/$defs/attribute" }
|
29
30
|
]
|
30
31
|
}
|
31
32
|
}
|
32
33
|
}
|
33
34
|
},
|
34
|
-
"
|
35
|
+
"accordion": {
|
35
36
|
"type": "object",
|
36
37
|
"required": ["label", "type"],
|
37
38
|
"properties": {
|
38
39
|
"type": {
|
39
40
|
"type": "string",
|
40
|
-
"
|
41
|
+
"const": "accordion"
|
41
42
|
},
|
42
43
|
"label": {
|
43
44
|
"type": "string"
|
@@ -50,6 +51,25 @@
|
|
50
51
|
}
|
51
52
|
}
|
52
53
|
},
|
54
|
+
"accordion_toggle": {
|
55
|
+
"type": "object",
|
56
|
+
"required": ["type", "toggle_attribute", "elements"],
|
57
|
+
"properties": {
|
58
|
+
"type": {
|
59
|
+
"type": "string",
|
60
|
+
"const": "accordion_toggle"
|
61
|
+
},
|
62
|
+
"toggle_attribute": {
|
63
|
+
"type": "string"
|
64
|
+
},
|
65
|
+
"elements": {
|
66
|
+
"type": "array",
|
67
|
+
"items": {
|
68
|
+
"oneOf": [{ "type": "string" }, { "$ref": "#/$defs/attribute" }]
|
69
|
+
}
|
70
|
+
}
|
71
|
+
}
|
72
|
+
},
|
53
73
|
"attribute": {
|
54
74
|
"type": "object",
|
55
75
|
"required": ["name", "type"],
|
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.
|
4
|
+
version: 2.1.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-
|
12
|
+
date: 2022-08-17 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/
|
153
|
+
- schema_definitions/layout.json
|
154
154
|
homepage: https://rubygems.org/gems/easol-canvas
|
155
155
|
licenses:
|
156
156
|
- MIT
|
@@ -170,7 +170,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
170
170
|
- !ruby/object:Gem::Version
|
171
171
|
version: '0'
|
172
172
|
requirements: []
|
173
|
-
rubygems_version: 3.
|
173
|
+
rubygems_version: 3.3.11
|
174
174
|
signing_key:
|
175
175
|
specification_version: 4
|
176
176
|
summary: CLI to help with building themes for Easol
|