easol-canvas 1.0.0 → 1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8570c1c4d1a8f7097f621722730ca8c882b633b901c8d22fb13f7dcbcb2ac8df
4
- data.tar.gz: d10b1319c6e1be3e0e43a77575fbf73f71f4a9f77582486d5b34d374d9c42105
3
+ metadata.gz: 5fe5e6dba572cf93a26d99560c7f36cd3f7f2188c019f5c5bd2429c6b897dd20
4
+ data.tar.gz: df34c9f374a73b17f47e4486345d6f6c21f4f184640d72976f664e3bf873e4ee
5
5
  SHA512:
6
- metadata.gz: 2dbfd55872ab41728e9243392a02c64551379cf42b99f59e455ade832fc028aa154b78e93600ec8bba8ac4fdcc52001850f2fd9cead452d64b896e1a997a0c63
7
- data.tar.gz: d6507b81b2fe0f72aad4407601606fa305b45e0d2142753eccc03cda5760277ceeaf54f83b6d8468274490e33afa4360da7174dd23599b4e5aa0a9fe484ab5d3
6
+ metadata.gz: d42d0a2cecd8040521956b2bb2a7380c08471e1aebfaf162a652b61a532bda67de5426ffba517b75bbc50449ac65eccbc6df78e009103c6ccc5e86874184c732
7
+ data.tar.gz: b4590073ce09eef3e258f924b66bfb0f996b88dacfbfbc72c1d0120f8fe96fafc30911015ae31df76836d665efea529db0af9bf3184cd6212747993f8c3a5d1e
data/lib/canvas/check.rb CHANGED
@@ -1,6 +1,9 @@
1
- require 'cli/ui'
1
+ # frozen_string_literal: true
2
+
3
+ require "cli/ui"
2
4
 
3
5
  module Canvas
6
+ # :documented:
4
7
  class Check
5
8
  attr_reader :offenses
6
9
 
@@ -1,4 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Canvas
4
+ # :documented:
2
5
  class RequiredFilesCheck < Check
3
6
  REQUIRED_FILES = [
4
7
  "templates/product/index.{html,liquid}",
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Canvas
4
+ # :documented:
5
+ # This check will validate the JSON objects that represent the
6
+ # custom types that are defined in the /types directory.
7
+ class ValidCustomTypesCheck < Check
8
+ def run
9
+ custom_type_files.each do |filename|
10
+ schema = extract_json(filename)
11
+ validator = Validator::CustomType.new(schema: schema)
12
+
13
+ next if validator.validate
14
+
15
+ validator.errors.each do |message|
16
+ @offenses << Offense.new(
17
+ message: "Invalid Custom Type: #{filename} - \n#{message}"
18
+ )
19
+ end
20
+ end
21
+ end
22
+
23
+ private
24
+
25
+ def custom_type_files
26
+ Dir.glob("types/*.json")
27
+ end
28
+
29
+ def extract_json(filename)
30
+ file = File.read(filename)
31
+ JSON.parse(file)
32
+ rescue JSON::ParserError
33
+ nil
34
+ end
35
+ end
36
+ end
@@ -1,4 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Canvas
4
+ # :documented:
2
5
  class ValidHtmlCheck < Check
3
6
  def run
4
7
  html_files.each do |filename|
@@ -1,4 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Canvas
4
+ # :documented:
2
5
  class ValidJsonCheck < Check
3
6
  def run
4
7
  json_files.each do |filename|
@@ -1,4 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Canvas
4
+ # :documented:
2
5
  class ValidLiquidCheck < Check
3
6
  def run
4
7
  register_tags!
data/lib/canvas/checks.rb CHANGED
@@ -1,4 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Canvas
4
+ # :documented:
2
5
  class Checks
3
6
  class << self
4
7
  def registered
@@ -10,7 +13,7 @@ module Canvas
10
13
  return if @checks.include?(klass)
11
14
  @checks << klass
12
15
  end
13
-
16
+
14
17
  def deregister_all!
15
18
  @checks = []
16
19
  end
data/lib/canvas/cli.rb CHANGED
@@ -1,12 +1,21 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "thor"
2
- require 'cli/ui'
4
+ require "cli/ui"
3
5
 
4
6
  module Canvas
7
+ # :documented:
5
8
  class Cli < Thor
6
9
  desc "lint", "Prints a hello world message"
7
10
  def lint
8
11
  CLI::UI::StdoutRouter.enable
9
12
  Canvas::Lint.new.run
10
13
  end
14
+
15
+ map %w[--version -v] => :__print_version
16
+ desc "--version, -v", "print the version"
17
+ def __print_version
18
+ puts Canvas::VERSION
19
+ end
11
20
  end
12
21
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :documented:
4
+ # This file is used to define globally accessible constants.
3
5
  module Canvas
4
6
  module Constants
5
7
  COLOR_PALETTE_VALUES = %w[
@@ -8,5 +10,22 @@ module Canvas
8
10
  body-bg
9
11
  body-color
10
12
  ].freeze
13
+
14
+ PRIMITIVE_TYPES = %w[
15
+ image
16
+ product
17
+ post
18
+ page
19
+ link
20
+ text
21
+ string
22
+ boolean
23
+ number
24
+ color
25
+ select
26
+ range
27
+ radio
28
+ variant
29
+ ].freeze
11
30
  end
12
31
  end
data/lib/canvas/lint.rb CHANGED
@@ -1,6 +1,9 @@
1
- require 'cli/ui'
1
+ # frozen_string_literal: true
2
+
3
+ require "cli/ui"
2
4
 
3
5
  module Canvas
6
+ #:documented:
4
7
  class Lint
5
8
  def run
6
9
  output_context = CLI::UI::SpinGroup.new(auto_debrief: false)
@@ -29,13 +32,13 @@ module Canvas
29
32
  end
30
33
 
31
34
  def debrief_message
32
- CLI::UI::Frame.open('Failures', color: :red) do
35
+ CLI::UI::Frame.open("Failures", color: :red) do
33
36
  failed_checks = @checks.filter(&:failed?)
34
37
  failed_checks.map do |check|
35
38
  CLI::UI::Frame.open(check.class.name, color: :red) do
36
- output = check.offenses.map do |offense|
39
+ output = check.offenses.map { |offense|
37
40
  CLI::UI.fmt "{{x}} #{offense.message}"
38
- end
41
+ }
39
42
  puts output.join("\n")
40
43
  end
41
44
  end
@@ -1,4 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Canvas
4
+ # :documented:
2
5
  class Offense
3
6
  attr_reader :message
4
7
 
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Canvas
3
4
  # :documented:
4
5
  # This service can be used to extract front matter from a liquid string.
@@ -0,0 +1,129 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Canvas
4
+ module Validator
5
+ # :documented:
6
+ # This class is used to validate the JSON defining a custom type.
7
+ #
8
+ # An example of a valid custom type:
9
+ # {
10
+ # "key": "faq",
11
+ # "name": "Faq",
12
+ # "attributes": [
13
+ # {
14
+ # "name": "question",
15
+ # "label": "Question",
16
+ # "type": "string"
17
+ # },
18
+ # {
19
+ # "name": "answer",
20
+ # "label": "Answer",
21
+ # "type": "text"
22
+ # }
23
+ # ]
24
+ # }
25
+ #
26
+ class CustomType
27
+ REQUIRED_KEYS = %w[key name attributes].freeze
28
+
29
+ attr_reader :schema, :errors
30
+
31
+ def initialize(schema:)
32
+ @schema = schema
33
+ @errors = []
34
+ end
35
+
36
+ def validate
37
+ ensure_valid_format &&
38
+ ensure_has_required_keys &&
39
+ ensure_no_unrecognized_keys &&
40
+ ensure_keys_are_correct_types &&
41
+ ensure_no_duplicate_attributes &&
42
+ ensure_attributes_are_valid &&
43
+ ensure_first_attribute_not_array
44
+
45
+ errors.empty?
46
+ end
47
+
48
+ private
49
+
50
+ def ensure_valid_format
51
+ return true if schema.is_a?(Hash)
52
+
53
+ @errors << "Schema is not in a valid format"
54
+ false
55
+ end
56
+
57
+ def ensure_has_required_keys
58
+ missing_keys = REQUIRED_KEYS - schema.keys
59
+ return true if missing_keys.empty?
60
+
61
+ @errors << "Missing required keys: #{missing_keys.join(', ')}"
62
+ false
63
+ end
64
+
65
+ def ensure_no_unrecognized_keys
66
+ unrecognized_keys = schema.keys - REQUIRED_KEYS
67
+ return true if unrecognized_keys.empty?
68
+
69
+ @errors << "Unrecognized keys: #{unrecognized_keys.join(', ')}"
70
+ false
71
+ end
72
+
73
+ def ensure_keys_are_correct_types
74
+ if !schema["key"].is_a?(String)
75
+ @errors << "\"key\" must be a string"
76
+ return false
77
+ end
78
+
79
+ if !schema["name"].is_a?(String)
80
+ @errors << "\"name\" must be a string"
81
+ return false
82
+ end
83
+
84
+ if !schema["attributes"].is_a?(Array) ||
85
+ schema["attributes"].empty? ||
86
+ schema["attributes"].any? { |a| !a.is_a?(Hash) }
87
+ @errors << "\"attributes\" must be an array of objects"
88
+ return false
89
+ end
90
+
91
+ true
92
+ end
93
+
94
+ def ensure_no_duplicate_attributes
95
+ attribute_names = schema["attributes"].map { |a| a["name"] }
96
+ duplicated_names = attribute_names.select { |a| attribute_names.count(a) > 1 }.uniq
97
+
98
+ return true if duplicated_names.empty?
99
+
100
+ @errors << "Some attributes are duplicated: #{duplicated_names.join(', ')}"
101
+ false
102
+ end
103
+
104
+ def ensure_attributes_are_valid
105
+ return true unless schema["attributes"]
106
+
107
+ schema["attributes"].each do |attribute_schema|
108
+ attr_validator = Validator::SchemaAttribute.new(
109
+ attribute: attribute_schema,
110
+ custom_types: []
111
+ )
112
+ next if attr_validator.validate
113
+
114
+ @errors << "Attribute \"#{attribute_schema['name']}\" is invalid "\
115
+ "- #{attr_validator.errors.join(', ')}"
116
+ end
117
+ end
118
+
119
+ def ensure_first_attribute_not_array
120
+ first_attribute = schema.fetch("attributes").first
121
+
122
+ return true if first_attribute.nil? || first_attribute["array"] != true
123
+
124
+ @errors << "The first attribute cannot be an array"
125
+ false
126
+ end
127
+ end
128
+ end
129
+ end
@@ -1,8 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "nokogiri"
2
4
  require "liquid"
3
5
 
4
6
  module Canvas
5
7
  module Validator
8
+ # :documented:
6
9
  class Html
7
10
  LIQUID_TAG = /#{::Liquid::TagStart}.*?#{::Liquid::TagEnd}/om
8
11
  LIQUID_VARIABLE = /#{::Liquid::VariableStart}.*?#{::Liquid::VariableEnd}/om
@@ -1,7 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "json"
2
4
 
3
5
  module Canvas
4
6
  module Validator
7
+ # :documented:
5
8
  class Json
6
9
  attr_reader :errors
7
10
 
@@ -1,8 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "nokogiri"
2
4
  require "liquid"
3
5
 
4
6
  module Canvas
5
7
  module Validator
8
+ # :documented:
6
9
  class Liquid
7
10
  attr_reader :errors
8
11
 
@@ -34,7 +34,6 @@ module Canvas
34
34
  "radio" => SchemaAttribute::Radio,
35
35
  "variant" => SchemaAttribute::Variant,
36
36
  }.freeze
37
- PRIMITIVE_TYPES = VALIDATORS.keys
38
37
  RESERVED_NAMES = %w[
39
38
  page
40
39
  company
@@ -71,7 +70,7 @@ module Canvas
71
70
  end
72
71
 
73
72
  def valid_types
74
- PRIMITIVE_TYPES + custom_type_keys
73
+ Constants::PRIMITIVE_TYPES + custom_type_keys
75
74
  end
76
75
 
77
76
  def validator_for_type
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Canvas
2
- VERSION = "1.0.0"
4
+ VERSION = "1.1.0"
3
5
  end
data/lib/canvas.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative "canvas/version"
2
4
  require_relative "canvas/constants"
3
5
  require_relative "canvas/cli"
@@ -11,18 +13,23 @@ require_relative "canvas/validators/schema_attributes/base"
11
13
 
12
14
  # The attribute validators need to be required before Canvas::Validator::SchemaAttribute
13
15
  attribute_validators = Dir["#{__dir__}/canvas/validators/schema_attributes/*.rb"]
14
- attribute_validators.each { |file| require file }
16
+ attribute_validators.each do |file|
17
+ require file
18
+ end
15
19
 
16
20
  files = Dir["#{__dir__}/canvas/{checks,services,validators}/*.rb"]
17
- files.each { |file| require file }
21
+ files.each do |file|
22
+ require file
23
+ end
18
24
 
19
25
  Canvas::Checks.register(Canvas::RequiredFilesCheck)
20
26
  Canvas::Checks.register(Canvas::ValidHtmlCheck)
21
27
  Canvas::Checks.register(Canvas::ValidLiquidCheck)
28
+ Canvas::Checks.register(Canvas::ValidJsonCheck)
22
29
  Canvas::Checks.register(Canvas::ValidBlockSchemasCheck)
23
30
  Canvas::Checks.register(Canvas::ValidMenuSchemaCheck)
24
31
  Canvas::Checks.register(Canvas::ValidFooterSchemaCheck)
25
- Canvas::Checks.register(Canvas::ValidJsonCheck)
32
+ Canvas::Checks.register(Canvas::ValidCustomTypesCheck)
26
33
 
27
34
  module Canvas
28
35
  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.0.0
4
+ version: 1.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-05-27 00:00:00.000000000 Z
12
+ date: 2022-06-01 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: thor
@@ -84,6 +84,7 @@ files:
84
84
  - lib/canvas/checks.rb
85
85
  - lib/canvas/checks/required_files_check.rb
86
86
  - lib/canvas/checks/valid_block_schemas_check.rb
87
+ - lib/canvas/checks/valid_custom_types_check.rb
87
88
  - lib/canvas/checks/valid_footer_schema_check.rb
88
89
  - lib/canvas/checks/valid_html_check.rb
89
90
  - lib/canvas/checks/valid_json_check.rb
@@ -97,6 +98,7 @@ files:
97
98
  - lib/canvas/services/fetch_custom_types.rb
98
99
  - lib/canvas/services/front_matter_extractor.rb
99
100
  - lib/canvas/validators/block_schema.rb
101
+ - lib/canvas/validators/custom_type.rb
100
102
  - lib/canvas/validators/footer_schema.rb
101
103
  - lib/canvas/validators/html.rb
102
104
  - lib/canvas/validators/json.rb