theme-check 1.12.0 → 1.13.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/CHANGELOG.md +16 -0
- data/data/shopify_liquid/deprecated_filters.json +22 -0
- data/data/shopify_liquid/documentation/filters.json +32 -0
- data/data/shopify_liquid/documentation/latest.json +1 -1
- data/data/shopify_liquid/documentation/objects.json +11 -11
- data/data/shopify_liquid/plus_labels.json +15 -0
- data/data/shopify_liquid/theme_app_extension_labels.json +3 -0
- data/docs/checks/app_block_valid_tags.md +1 -0
- data/lib/theme_check/checks/app_block_valid_tags.rb +4 -0
- data/lib/theme_check/language_server/completion_provider.rb +10 -0
- data/lib/theme_check/language_server/completion_providers/assignments_completion_provider.rb +9 -5
- data/lib/theme_check/language_server/completion_providers/filter_completion_provider.rb +1 -1
- data/lib/theme_check/language_server/completion_providers/object_attribute_completion_provider.rb +1 -0
- data/lib/theme_check/language_server/completion_providers/object_completion_provider.rb +6 -4
- data/lib/theme_check/language_server/variable_lookup_finder/assignments_finder/scope.rb +18 -15
- data/lib/theme_check/language_server/variable_lookup_finder/assignments_finder/scope_visitor.rb +3 -1
- data/lib/theme_check/language_server/variable_lookup_finder/constants.rb +1 -0
- data/lib/theme_check/language_server/variable_lookup_finder/tolerant_parser.rb +20 -0
- data/lib/theme_check/language_server/variable_lookup_finder.rb +10 -3
- data/lib/theme_check/shopify_liquid/deprecated_filter.rb +1 -1
- data/lib/theme_check/shopify_liquid/filter.rb +35 -7
- data/lib/theme_check/shopify_liquid/object.rb +8 -7
- data/lib/theme_check/shopify_liquid/source_index.rb +21 -1
- data/lib/theme_check/shopify_liquid/tag.rb +11 -5
- data/lib/theme_check/tags.rb +19 -0
- data/lib/theme_check/version.rb +1 -1
- metadata +5 -8
- data/data/shopify_liquid/deprecated_filters.yml +0 -14
- data/data/shopify_liquid/filters.yml +0 -211
- data/data/shopify_liquid/objects.yml +0 -84
- data/data/shopify_liquid/plus_objects.yml +0 -15
- data/data/shopify_liquid/tags.yml +0 -30
- data/data/shopify_liquid/theme_app_extension_objects.yml +0 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6510c266c71be36555ad42b3de0dc88db11710ac631dd2d7292175764b3ce51f
|
|
4
|
+
data.tar.gz: d8eb627ff4f5de44cfea7a21049f37c42c007ff617fe2f07760ade8e1b0dc283
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 79f4683785b839a91731540fdf4b0e23d1d4f4a0a949aae3beb8637f651b8b0030ef5a3f9506da5de63109636410fc4cdb31616aade995442e61de43da4e2c55
|
|
7
|
+
data.tar.gz: 5dda4447bb00c1b4f225255c628d9f5ab6c5e17c619065681631d68953e3b0b4562a523a3c359a5e566007de0042282aec775f82dcecd05e2c4c5b4c8eee0003
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,19 @@
|
|
|
1
|
+
|
|
2
|
+
v1.13.0 / 2023-01-04
|
|
3
|
+
==================
|
|
4
|
+
|
|
5
|
+
* Add support for new sections liquid tag in theme check ([#694](https://github.com/Shopify/theme-check/issues/694))
|
|
6
|
+
|
|
7
|
+
v1.12.1 / 2022-12-15
|
|
8
|
+
==================
|
|
9
|
+
|
|
10
|
+
* `ObjectCompletionProvider` should not provide completion items that don't live in the `SourceIndex` ([#690](https://github.com/Shopify/theme-check/issues/690))
|
|
11
|
+
* Suggest deprecated completion items at the end of the list ([#688](https://github.com/Shopify/theme-check/issues/688))
|
|
12
|
+
* Only suggest filters in SourceIndex ([#689](https://github.com/Shopify/theme-check/issues/689))
|
|
13
|
+
* Remove the `data/shopify_liquid/(tags|filters|objects).yml` files ([#674](https://github.com/Shopify/theme-check/issues/674))
|
|
14
|
+
* Introduce support to range iterations and SFR tags ([#685](https://github.com/Shopify/theme-check/issues/685))
|
|
15
|
+
* Suggest objects for `paginate` ([#686](https://github.com/Shopify/theme-check/issues/686))
|
|
16
|
+
|
|
1
17
|
v1.12.0 / 2022-12-12
|
|
2
18
|
==================
|
|
3
19
|
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"Liquid::ColorFilter": {
|
|
3
|
+
"hex_to_rgba": [
|
|
4
|
+
"color_to_rgb",
|
|
5
|
+
"color_modify"
|
|
6
|
+
]
|
|
7
|
+
},
|
|
8
|
+
"Liquid::UrlFilter": {
|
|
9
|
+
"img_url": [
|
|
10
|
+
"image_url"
|
|
11
|
+
],
|
|
12
|
+
"img_tag": [
|
|
13
|
+
"image_tag"
|
|
14
|
+
],
|
|
15
|
+
"collection_img_url": [
|
|
16
|
+
"img_url"
|
|
17
|
+
],
|
|
18
|
+
"product_img_url": [
|
|
19
|
+
"img_url"
|
|
20
|
+
]
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -1,4 +1,36 @@
|
|
|
1
1
|
[
|
|
2
|
+
{
|
|
3
|
+
"category": "cart",
|
|
4
|
+
"deprecated": false,
|
|
5
|
+
"deprecation_reason": "",
|
|
6
|
+
"description": "",
|
|
7
|
+
"parameters": [
|
|
8
|
+
|
|
9
|
+
],
|
|
10
|
+
"return_type": [
|
|
11
|
+
{
|
|
12
|
+
"type": "number",
|
|
13
|
+
"name": "",
|
|
14
|
+
"description": "",
|
|
15
|
+
"array_value": ""
|
|
16
|
+
}
|
|
17
|
+
],
|
|
18
|
+
"examples": [
|
|
19
|
+
{
|
|
20
|
+
"name": "",
|
|
21
|
+
"description": "",
|
|
22
|
+
"syntax": "",
|
|
23
|
+
"path": "/cart",
|
|
24
|
+
"raw_liquid": "{{ cart | item_count_for_variant: 39888235757633 }}",
|
|
25
|
+
"parameter": false,
|
|
26
|
+
"display_type": "text",
|
|
27
|
+
"show_data_tab": true
|
|
28
|
+
}
|
|
29
|
+
],
|
|
30
|
+
"summary": "Returns the total item count of a variant in the cart.",
|
|
31
|
+
"syntax": "cart | item_count_for_variant: {variant_id}",
|
|
32
|
+
"name": "item_count_for_variant"
|
|
33
|
+
},
|
|
2
34
|
{
|
|
3
35
|
"category": "collection",
|
|
4
36
|
"deprecated": false,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{ "revision": "
|
|
1
|
+
{ "revision": "dc81fa4ea744b4fbd308801f059755084090fe42" }
|
|
@@ -568,7 +568,12 @@
|
|
|
568
568
|
"data_from_file": ""
|
|
569
569
|
},
|
|
570
570
|
"return_type": [
|
|
571
|
-
|
|
571
|
+
{
|
|
572
|
+
"type": "array",
|
|
573
|
+
"name": "",
|
|
574
|
+
"description": "",
|
|
575
|
+
"array_value": "collection"
|
|
576
|
+
}
|
|
572
577
|
]
|
|
573
578
|
},
|
|
574
579
|
{
|
|
@@ -12407,12 +12412,12 @@
|
|
|
12407
12412
|
}
|
|
12408
12413
|
],
|
|
12409
12414
|
"summary": "Returns `true` when being referenced inside a section that's been rendered using the Product Recommendations API and\nthe Section Rendering API. Returns `false` if not.",
|
|
12410
|
-
"name": "
|
|
12415
|
+
"name": "performed?"
|
|
12411
12416
|
},
|
|
12412
12417
|
{
|
|
12413
12418
|
"deprecated": false,
|
|
12414
12419
|
"deprecation_reason": "",
|
|
12415
|
-
"description": "If `
|
|
12420
|
+
"description": "If `performed?` is `false`, then an [EmptyDrop](/api/liquid/basics#emptydrop) is returned.",
|
|
12416
12421
|
"examples": [
|
|
12417
12422
|
|
|
12418
12423
|
],
|
|
@@ -12430,7 +12435,7 @@
|
|
|
12430
12435
|
{
|
|
12431
12436
|
"deprecated": false,
|
|
12432
12437
|
"deprecation_reason": "",
|
|
12433
|
-
"description": "If `
|
|
12438
|
+
"description": "If `performed?` is `false`, then 0 is returned.",
|
|
12434
12439
|
"examples": [
|
|
12435
12440
|
|
|
12436
12441
|
],
|
|
@@ -12448,7 +12453,7 @@
|
|
|
12448
12453
|
{
|
|
12449
12454
|
"deprecated": false,
|
|
12450
12455
|
"deprecation_reason": "",
|
|
12451
|
-
"description": "If `
|
|
12456
|
+
"description": "If `performed?` is `false`, then `nil` is returned.",
|
|
12452
12457
|
"examples": [
|
|
12453
12458
|
|
|
12454
12459
|
],
|
|
@@ -15075,12 +15080,7 @@
|
|
|
15075
15080
|
|
|
15076
15081
|
],
|
|
15077
15082
|
"return_type": [
|
|
15078
|
-
|
|
15079
|
-
"type": "metafield",
|
|
15080
|
-
"name": "",
|
|
15081
|
-
"description": "",
|
|
15082
|
-
"array_value": ""
|
|
15083
|
-
}
|
|
15083
|
+
|
|
15084
15084
|
],
|
|
15085
15085
|
"summary": "The [metafields](/api/liquid/objects/metafield) applied to the store.",
|
|
15086
15086
|
"name": "metafields"
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
[
|
|
2
|
+
"alternative_payment_methods",
|
|
3
|
+
"breadcrumb",
|
|
4
|
+
"checkout_html_classes",
|
|
5
|
+
"checkout_scripts",
|
|
6
|
+
"checkout_stylesheets",
|
|
7
|
+
"content_for_footer",
|
|
8
|
+
"content_for_logo",
|
|
9
|
+
"content_for_order_summary",
|
|
10
|
+
"direction",
|
|
11
|
+
"locale",
|
|
12
|
+
"order_summary_toggle",
|
|
13
|
+
"skip_to_content_link",
|
|
14
|
+
"tracking_code"
|
|
15
|
+
]
|
|
@@ -11,6 +11,7 @@ This rule verifies none of the below tags are used in theme app extension blocks
|
|
|
11
11
|
- `{% include 'foo' %}`
|
|
12
12
|
- `{% layout 'foo' %}`
|
|
13
13
|
- `{% section 'foo' %}`
|
|
14
|
+
- `{% sections 'foo' %}`
|
|
14
15
|
|
|
15
16
|
:-1: **Incorrect** code for this check occurs with the use of any of the above tags in the liquid code of theme app extension blocks.
|
|
16
17
|
|
|
@@ -38,6 +38,16 @@ module ThemeCheck
|
|
|
38
38
|
},
|
|
39
39
|
}
|
|
40
40
|
end
|
|
41
|
+
|
|
42
|
+
def format_hash(entry)
|
|
43
|
+
return {} unless entry
|
|
44
|
+
return { sortText: entry.name } unless entry.deprecated?
|
|
45
|
+
|
|
46
|
+
{
|
|
47
|
+
tags: [CompletionItemTag::DEPRECATED],
|
|
48
|
+
sortText: "~#{entry.name}",
|
|
49
|
+
}
|
|
50
|
+
end
|
|
41
51
|
end
|
|
42
52
|
end
|
|
43
53
|
end
|
data/lib/theme_check/language_server/completion_providers/assignments_completion_provider.rb
CHANGED
|
@@ -13,11 +13,10 @@ module ThemeCheck
|
|
|
13
13
|
|
|
14
14
|
finder = VariableLookupFinder::AssignmentsFinder.new(content)
|
|
15
15
|
finder.find!
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
end
|
|
16
|
+
finder
|
|
17
|
+
.assignments
|
|
18
|
+
.map { |label, potential_lookup| object_to_completion(label, object_name(potential_lookup)) }
|
|
19
|
+
.compact
|
|
21
20
|
end
|
|
22
21
|
|
|
23
22
|
private
|
|
@@ -31,6 +30,11 @@ module ThemeCheck
|
|
|
31
30
|
**doc_hash(content),
|
|
32
31
|
}
|
|
33
32
|
end
|
|
33
|
+
|
|
34
|
+
def object_name(potential_lookup)
|
|
35
|
+
object, _property = VariableLookupTraverser.lookup_object_and_property(potential_lookup)
|
|
36
|
+
object&.name
|
|
37
|
+
end
|
|
34
38
|
end
|
|
35
39
|
end
|
|
36
40
|
end
|
|
@@ -11,8 +11,9 @@ module ThemeCheck
|
|
|
11
11
|
return [] unless variable_lookup.lookups.empty?
|
|
12
12
|
return [] if content[context.cursor - 1] == "."
|
|
13
13
|
|
|
14
|
-
ShopifyLiquid::
|
|
15
|
-
.
|
|
14
|
+
ShopifyLiquid::SourceIndex
|
|
15
|
+
.objects
|
|
16
|
+
.select { |object| object.name.start_with?(partial(variable_lookup)) }
|
|
16
17
|
.map { |object| object_to_completion(object) }
|
|
17
18
|
end
|
|
18
19
|
|
|
@@ -23,11 +24,12 @@ module ThemeCheck
|
|
|
23
24
|
private
|
|
24
25
|
|
|
25
26
|
def object_to_completion(object)
|
|
26
|
-
content = ShopifyLiquid::Documentation.
|
|
27
|
+
content = ShopifyLiquid::Documentation.render_doc(object)
|
|
27
28
|
|
|
28
29
|
{
|
|
29
|
-
label: object,
|
|
30
|
+
label: object.name,
|
|
30
31
|
kind: CompletionItemKinds::VARIABLE,
|
|
32
|
+
**format_hash(object),
|
|
31
33
|
**doc_hash(content),
|
|
32
34
|
}
|
|
33
35
|
end
|
|
@@ -20,33 +20,36 @@ module ThemeCheck
|
|
|
20
20
|
case tag
|
|
21
21
|
when Liquid::Assign
|
|
22
22
|
variable_name = tag.to
|
|
23
|
-
variables[variable_name] =
|
|
23
|
+
variables[variable_name] = as_potential_lookup(tag.from.name)
|
|
24
24
|
when Liquid::For, Liquid::TableRow
|
|
25
25
|
variable_name = tag.variable_name
|
|
26
|
-
variables[variable_name] =
|
|
26
|
+
variables[variable_name] = as_potential_lookup(tag.collection_name, ['first'])
|
|
27
27
|
end
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
private
|
|
31
31
|
|
|
32
|
-
def
|
|
33
|
-
variable_lookup
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
32
|
+
def as_potential_lookup(variable_lookup, default_lookups = [])
|
|
33
|
+
case variable_lookup
|
|
34
|
+
when Liquid::VariableLookup
|
|
35
|
+
potential_lookup(variable_lookup, default_lookups)
|
|
36
|
+
when Liquid::RangeLookup
|
|
37
|
+
as_potential_lookup(variable_lookup.start_obj)
|
|
38
|
+
when Enumerable
|
|
39
|
+
as_potential_lookup(variable_lookup.first)
|
|
40
|
+
else
|
|
41
|
+
literal_lookup(variable_lookup)
|
|
37
42
|
end
|
|
38
|
-
|
|
39
|
-
name = variable_lookup.name
|
|
40
|
-
lookups = variable_lookup.lookups
|
|
41
|
-
|
|
42
|
-
PotentialLookup.new(name, lookups, variables)
|
|
43
43
|
end
|
|
44
44
|
|
|
45
|
-
def
|
|
46
|
-
|
|
45
|
+
def literal_lookup(variable_lookup)
|
|
46
|
+
name = input_type_of(variable_lookup)
|
|
47
|
+
PotentialLookup.new(name, [], variables)
|
|
48
|
+
end
|
|
47
49
|
|
|
50
|
+
def potential_lookup(variable_lookup, default_lookups)
|
|
48
51
|
name = variable_lookup.name
|
|
49
|
-
lookups =
|
|
52
|
+
lookups = variable_lookup.lookups.concat(default_lookups)
|
|
50
53
|
|
|
51
54
|
PotentialLookup.new(name, lookups, variables)
|
|
52
55
|
end
|
data/lib/theme_check/language_server/variable_lookup_finder/assignments_finder/scope_visitor.rb
CHANGED
|
@@ -5,6 +5,8 @@ module ThemeCheck
|
|
|
5
5
|
module VariableLookupFinder
|
|
6
6
|
class AssignmentsFinder
|
|
7
7
|
class ScopeVisitor
|
|
8
|
+
SCOPE_UNAWARE_NODES = %i(range range_lookup variable variable_lookup)
|
|
9
|
+
|
|
8
10
|
attr_reader :global_scope, :current_scope
|
|
9
11
|
|
|
10
12
|
def initialize
|
|
@@ -22,7 +24,7 @@ module ThemeCheck
|
|
|
22
24
|
private
|
|
23
25
|
|
|
24
26
|
def visit(node, scope)
|
|
25
|
-
return if node.type_name
|
|
27
|
+
return if SCOPE_UNAWARE_NODES.include?(node.type_name)
|
|
26
28
|
|
|
27
29
|
method = :"on_#{node.type_name}"
|
|
28
30
|
scope = @node_handler.send(method, node, scope) if @node_handler.respond_to?(method)
|
|
@@ -73,12 +73,32 @@ module ThemeCheck
|
|
|
73
73
|
include TolerantBlockBody
|
|
74
74
|
end
|
|
75
75
|
|
|
76
|
+
class Paginate < Liquid::Tag
|
|
77
|
+
include TolerantBlockBody
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
class Form < Liquid::Tag
|
|
81
|
+
include TolerantBlockBody
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
class Style < Liquid::Tag
|
|
85
|
+
include TolerantBlockBody
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
class Stylesheet < Liquid::Tag
|
|
89
|
+
include TolerantBlockBody
|
|
90
|
+
end
|
|
91
|
+
|
|
76
92
|
def initialize(standard_tags)
|
|
77
93
|
@standard_tags = standard_tags
|
|
78
94
|
@tolerant_tags = {
|
|
79
95
|
'case' => Case,
|
|
80
96
|
'for' => For,
|
|
97
|
+
'form' => Form,
|
|
81
98
|
'if' => If,
|
|
99
|
+
'paginate' => Paginate,
|
|
100
|
+
'style' => Style,
|
|
101
|
+
'stylesheet' => Stylesheet,
|
|
82
102
|
'tablerow' => TableRow,
|
|
83
103
|
'unless' => Unless,
|
|
84
104
|
}
|
|
@@ -30,18 +30,21 @@ module ThemeCheck
|
|
|
30
30
|
private
|
|
31
31
|
|
|
32
32
|
def potential_lookup(variable, context)
|
|
33
|
-
return variable if context.buffer.nil? || context.buffer.empty?
|
|
33
|
+
return as_potential_lookup(variable) if context.buffer.nil? || context.buffer.empty?
|
|
34
34
|
|
|
35
35
|
buffer = context.buffer[0...context.absolute_cursor]
|
|
36
36
|
lookups = variable.lookups
|
|
37
37
|
assignments = find_assignments(buffer)
|
|
38
|
+
assignments_path = []
|
|
38
39
|
|
|
39
|
-
while assignments[variable.name]
|
|
40
|
+
while assignments[variable.name] && !assignments_path.include?(assignments[variable.name])
|
|
40
41
|
variable = assignments[variable.name]
|
|
41
42
|
lookups = variable.lookups + lookups
|
|
43
|
+
|
|
44
|
+
assignments_path << variable
|
|
42
45
|
end
|
|
43
46
|
|
|
44
|
-
|
|
47
|
+
as_potential_lookup(variable, lookups: lookups)
|
|
45
48
|
end
|
|
46
49
|
|
|
47
50
|
def find_assignments(buffer)
|
|
@@ -50,6 +53,10 @@ module ThemeCheck
|
|
|
50
53
|
finder.assignments
|
|
51
54
|
end
|
|
52
55
|
|
|
56
|
+
def as_potential_lookup(variable, lookups: nil)
|
|
57
|
+
PotentialLookup.new(variable.name, lookups || variable.lookups)
|
|
58
|
+
end
|
|
59
|
+
|
|
53
60
|
def cursor_is_on_bracket_position_that_cant_be_completed(content, cursor)
|
|
54
61
|
content_before_cursor = content[0..cursor - 1]
|
|
55
62
|
return false unless /[\[\]]/.match?(content_before_cursor)
|
|
@@ -17,7 +17,7 @@ module ThemeCheck
|
|
|
17
17
|
private
|
|
18
18
|
|
|
19
19
|
def all
|
|
20
|
-
@all ||=
|
|
20
|
+
@all ||= SourceIndex.deprecated_filters
|
|
21
21
|
.values
|
|
22
22
|
.each_with_object({}) do |filters, acc|
|
|
23
23
|
filters.each do |(filter, alternatives)|
|
|
@@ -3,17 +3,45 @@ require 'yaml'
|
|
|
3
3
|
|
|
4
4
|
module ThemeCheck
|
|
5
5
|
module ShopifyLiquid
|
|
6
|
-
# TODO: (6/6) https://github.com/Shopify/theme-check/issues/656
|
|
7
|
-
# -
|
|
8
|
-
# Remove 'filters.yml' in favor of 'SourceIndex.filters'
|
|
9
|
-
# -
|
|
10
6
|
module Filter
|
|
11
7
|
extend self
|
|
12
8
|
|
|
9
|
+
LABELS_NOT_IN_SOURCE_INDEX = [
|
|
10
|
+
"h",
|
|
11
|
+
"installments_pricing",
|
|
12
|
+
"sentence",
|
|
13
|
+
"t",
|
|
14
|
+
"app_block_path_for",
|
|
15
|
+
"dev_shop?",
|
|
16
|
+
"app_extension_path_for",
|
|
17
|
+
"global_block_type?",
|
|
18
|
+
"app_block_path?",
|
|
19
|
+
"app_extension_path?",
|
|
20
|
+
"app_snippet_path?",
|
|
21
|
+
"registration_uuid_from",
|
|
22
|
+
"handle_from",
|
|
23
|
+
"camelcase",
|
|
24
|
+
"format_code",
|
|
25
|
+
"handle",
|
|
26
|
+
"encode_url_component",
|
|
27
|
+
"recover_password_link",
|
|
28
|
+
"delete_customer_address_link",
|
|
29
|
+
"edit_customer_address_link",
|
|
30
|
+
"cancel_customer_order_link",
|
|
31
|
+
"unit",
|
|
32
|
+
"weight",
|
|
33
|
+
"paragraphize",
|
|
34
|
+
"excerpt",
|
|
35
|
+
"pad_spaces",
|
|
36
|
+
"distance_from",
|
|
37
|
+
"theme_url",
|
|
38
|
+
"link_to_theme",
|
|
39
|
+
"_online_store_editor_live_setting",
|
|
40
|
+
"debug",
|
|
41
|
+
]
|
|
42
|
+
|
|
13
43
|
def labels
|
|
14
|
-
@labels ||=
|
|
15
|
-
.values
|
|
16
|
-
.flatten
|
|
44
|
+
@labels ||= SourceIndex.filters.map(&:name) + LABELS_NOT_IN_SOURCE_INDEX
|
|
17
45
|
end
|
|
18
46
|
end
|
|
19
47
|
end
|
|
@@ -3,23 +3,24 @@ require 'yaml'
|
|
|
3
3
|
|
|
4
4
|
module ThemeCheck
|
|
5
5
|
module ShopifyLiquid
|
|
6
|
-
# TODO: (4/6) https://github.com/Shopify/theme-check/issues/656
|
|
7
|
-
# -
|
|
8
|
-
# Remove 'objects.yml' in favor of 'SourceIndex.objects'
|
|
9
|
-
# -
|
|
10
6
|
module Object
|
|
11
7
|
extend self
|
|
12
8
|
|
|
9
|
+
LABELS_NOT_IN_SOURCE_INDEX = [
|
|
10
|
+
"customer_address",
|
|
11
|
+
"product_variant",
|
|
12
|
+
].freeze
|
|
13
|
+
|
|
13
14
|
def labels
|
|
14
|
-
@labels ||=
|
|
15
|
+
@labels ||= SourceIndex.objects.map(&:name) + LABELS_NOT_IN_SOURCE_INDEX
|
|
15
16
|
end
|
|
16
17
|
|
|
17
18
|
def plus_labels
|
|
18
|
-
@plus_labels ||=
|
|
19
|
+
@plus_labels ||= SourceIndex.plus_labels
|
|
19
20
|
end
|
|
20
21
|
|
|
21
22
|
def theme_app_extension_labels
|
|
22
|
-
@theme_app_extension_labels ||=
|
|
23
|
+
@theme_app_extension_labels ||= SourceIndex.theme_app_extension_labels
|
|
23
24
|
end
|
|
24
25
|
end
|
|
25
26
|
end
|
|
@@ -21,7 +21,11 @@ module ThemeCheck
|
|
|
21
21
|
@objects ||= ObjectState.mark_up_to_date &&
|
|
22
22
|
load_file(:objects)
|
|
23
23
|
.concat(built_in_objects)
|
|
24
|
-
.
|
|
24
|
+
.filter_map do |hash|
|
|
25
|
+
next if (theme_app_extension_labels + labels_only_exposed_in_certain_contexts).include?(hash['name'])
|
|
26
|
+
|
|
27
|
+
ObjectEntry.new(hash)
|
|
28
|
+
end
|
|
25
29
|
end
|
|
26
30
|
|
|
27
31
|
def tags
|
|
@@ -32,6 +36,22 @@ module ThemeCheck
|
|
|
32
36
|
.map { |hash| TagEntry.new(hash) }
|
|
33
37
|
end
|
|
34
38
|
|
|
39
|
+
def plus_labels
|
|
40
|
+
@plus_objects ||= load_file("../plus_labels")
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def theme_app_extension_labels
|
|
44
|
+
@theme_app_extension_labels ||= load_file("../theme_app_extension_labels")
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def labels_only_exposed_in_certain_contexts
|
|
48
|
+
['robots'].freeze
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def deprecated_filters
|
|
52
|
+
@deprecated_filters ||= load_file("../deprecated_filters")
|
|
53
|
+
end
|
|
54
|
+
|
|
35
55
|
private
|
|
36
56
|
|
|
37
57
|
def load_file(file_name)
|
|
@@ -6,6 +6,8 @@ module ThemeCheck
|
|
|
6
6
|
module Tag
|
|
7
7
|
extend self
|
|
8
8
|
|
|
9
|
+
LABELS_NOT_IN_SOURCE_INDEX = ["elsif", "ifchanged", { "schema" => "endschema" }, "when"]
|
|
10
|
+
|
|
9
11
|
def labels
|
|
10
12
|
@labels ||= tags_file_contents
|
|
11
13
|
.map { |x| to_label(x) }
|
|
@@ -37,12 +39,16 @@ module ThemeCheck
|
|
|
37
39
|
label.keys[0]
|
|
38
40
|
end
|
|
39
41
|
|
|
40
|
-
# TODO: (5/6) https://github.com/Shopify/theme-check/issues/656
|
|
41
|
-
# -
|
|
42
|
-
# Remove 'tags.yml' in favor of 'SourceIndex.tags'
|
|
43
|
-
# -
|
|
44
42
|
def tags_file_contents
|
|
45
|
-
@tags_file_contents ||=
|
|
43
|
+
@tags_file_contents ||= SourceIndex.tags.map do |tag|
|
|
44
|
+
opening_tag = tag.name
|
|
45
|
+
closing_tag = "end#{opening_tag}"
|
|
46
|
+
if tag.hash['syntax'] =~ /#{opening_tag}.+#{closing_tag}/m
|
|
47
|
+
{ opening_tag => closing_tag }
|
|
48
|
+
else
|
|
49
|
+
opening_tag
|
|
50
|
+
end
|
|
51
|
+
end + LABELS_NOT_IN_SOURCE_INDEX
|
|
46
52
|
end
|
|
47
53
|
end
|
|
48
54
|
end
|
data/lib/theme_check/tags.rb
CHANGED
|
@@ -22,6 +22,24 @@ module ThemeCheck
|
|
|
22
22
|
end
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
+
class Sections < Liquid::Tag
|
|
26
|
+
SYNTAX = /\A\s*(?<sections_name>#{Liquid::QuotedString})\s*\z/o
|
|
27
|
+
|
|
28
|
+
attr_reader :sections_name
|
|
29
|
+
|
|
30
|
+
def initialize(tag_name, markup, options)
|
|
31
|
+
super
|
|
32
|
+
|
|
33
|
+
match = markup.match(SYNTAX)
|
|
34
|
+
raise(
|
|
35
|
+
Liquid::SyntaxError,
|
|
36
|
+
"Error in tag 'sections' - Valid syntax: sections '[type]'",
|
|
37
|
+
) unless match
|
|
38
|
+
@sections_name = match[:sections_name].tr(%('"), '')
|
|
39
|
+
@sections_name.chomp!(".liquid") if @sections_name.end_with?(".liquid")
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
25
43
|
class Form < Liquid::Block
|
|
26
44
|
TAG_ATTRIBUTES = /([\w\-]+)\s*:\s*(#{Liquid::QuotedFragment})/o
|
|
27
45
|
# Matches forms with arguments:
|
|
@@ -204,6 +222,7 @@ module ThemeCheck
|
|
|
204
222
|
register_tag('render', Render)
|
|
205
223
|
register_tag('paginate', Paginate)
|
|
206
224
|
register_tag('section', Section)
|
|
225
|
+
register_tag('sections', Sections)
|
|
207
226
|
register_tag('style', Style)
|
|
208
227
|
register_tag('schema', Schema)
|
|
209
228
|
register_tag('javascript', Javascript)
|
data/lib/theme_check/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: theme-check
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.13.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Marc-André Cournoyer
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2023-01-04 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: liquid
|
|
@@ -83,16 +83,13 @@ files:
|
|
|
83
83
|
- config/nothing.yml
|
|
84
84
|
- config/theme_app_extension.yml
|
|
85
85
|
- data/shopify_liquid/built_in_liquid_objects.json
|
|
86
|
-
- data/shopify_liquid/deprecated_filters.
|
|
86
|
+
- data/shopify_liquid/deprecated_filters.json
|
|
87
87
|
- data/shopify_liquid/documentation/filters.json
|
|
88
88
|
- data/shopify_liquid/documentation/latest.json
|
|
89
89
|
- data/shopify_liquid/documentation/objects.json
|
|
90
90
|
- data/shopify_liquid/documentation/tags.json
|
|
91
|
-
- data/shopify_liquid/
|
|
92
|
-
- data/shopify_liquid/
|
|
93
|
-
- data/shopify_liquid/plus_objects.yml
|
|
94
|
-
- data/shopify_liquid/tags.yml
|
|
95
|
-
- data/shopify_liquid/theme_app_extension_objects.yml
|
|
91
|
+
- data/shopify_liquid/plus_labels.json
|
|
92
|
+
- data/shopify_liquid/theme_app_extension_labels.json
|
|
96
93
|
- data/shopify_translation_keys.yml
|
|
97
94
|
- dev.yml
|
|
98
95
|
- docs/api/check.md
|
|
@@ -1,211 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
# Here's an example workflow that's going to get ya the list of filters available
|
|
3
|
-
# ```bash
|
|
4
|
-
# spin up storefront-renderer
|
|
5
|
-
# spin ssh
|
|
6
|
-
# cd storefront-renderer
|
|
7
|
-
# bundle exec rake console
|
|
8
|
-
# ```
|
|
9
|
-
# ```ruby
|
|
10
|
-
# Pathname(ENV["HOME"]).join('filters.yml').write(YAML.dump(Liquid::StrainerFactory.global_filter_names))
|
|
11
|
-
# ```
|
|
12
|
-
# ```bash
|
|
13
|
-
# exit
|
|
14
|
-
# scp $(spin show -o fqdn):/filters.yml .
|
|
15
|
-
# ```
|
|
16
|
-
# The list of filters is now in a file named filters.yml in your $(pwd).
|
|
17
|
-
# Note that it'll probably need a bit of massaging before including here...
|
|
18
|
-
Liquid::StandardFilters:
|
|
19
|
-
- times
|
|
20
|
-
- h
|
|
21
|
-
- uniq
|
|
22
|
-
- compact
|
|
23
|
-
- url_encode
|
|
24
|
-
- escape
|
|
25
|
-
- escape_once
|
|
26
|
-
- url_decode
|
|
27
|
-
- base64_encode
|
|
28
|
-
- base64_decode
|
|
29
|
-
- base64_url_safe_encode
|
|
30
|
-
- base64_url_safe_decode
|
|
31
|
-
- truncatewords
|
|
32
|
-
- strip_html
|
|
33
|
-
- strip_newlines
|
|
34
|
-
- replace
|
|
35
|
-
- remove
|
|
36
|
-
- sort_natural
|
|
37
|
-
- replace_first
|
|
38
|
-
- replace_last
|
|
39
|
-
- remove_first
|
|
40
|
-
- remove_last
|
|
41
|
-
- newline_to_br
|
|
42
|
-
- upcase
|
|
43
|
-
- downcase
|
|
44
|
-
- capitalize
|
|
45
|
-
- divided_by
|
|
46
|
-
- minus
|
|
47
|
-
- at_most
|
|
48
|
-
- at_least
|
|
49
|
-
- size
|
|
50
|
-
- last
|
|
51
|
-
- split
|
|
52
|
-
- append
|
|
53
|
-
- reverse
|
|
54
|
-
- concat
|
|
55
|
-
- prepend
|
|
56
|
-
- join
|
|
57
|
-
- strip
|
|
58
|
-
- lstrip
|
|
59
|
-
- rstrip
|
|
60
|
-
- sort
|
|
61
|
-
- where
|
|
62
|
-
- map
|
|
63
|
-
- default
|
|
64
|
-
- first
|
|
65
|
-
- slice
|
|
66
|
-
- modulo
|
|
67
|
-
- abs
|
|
68
|
-
- date
|
|
69
|
-
- ceil
|
|
70
|
-
- round
|
|
71
|
-
- truncate
|
|
72
|
-
- plus
|
|
73
|
-
- floor
|
|
74
|
-
FormFilter:
|
|
75
|
-
- payment_terms
|
|
76
|
-
- installments_pricing
|
|
77
|
-
- default_errors
|
|
78
|
-
- payment_button
|
|
79
|
-
DateFilter:
|
|
80
|
-
- date
|
|
81
|
-
I18nFilter:
|
|
82
|
-
- translate
|
|
83
|
-
- time_tag
|
|
84
|
-
- sentence
|
|
85
|
-
- t
|
|
86
|
-
- date
|
|
87
|
-
- app_block_path_for
|
|
88
|
-
- dev_shop?
|
|
89
|
-
- app_extension_path_for
|
|
90
|
-
- global_block_type?
|
|
91
|
-
- app_block_path?
|
|
92
|
-
- app_extension_path?
|
|
93
|
-
- app_snippet_path?
|
|
94
|
-
- registration_uuid_from
|
|
95
|
-
- handle_from
|
|
96
|
-
UrlFilter:
|
|
97
|
-
- stylesheet_tag
|
|
98
|
-
- script_tag
|
|
99
|
-
- img_tag
|
|
100
|
-
- link_to
|
|
101
|
-
- shopify_asset_url
|
|
102
|
-
- payment_type_img_url
|
|
103
|
-
- payment_type_svg_tag
|
|
104
|
-
- placeholder_svg_tag
|
|
105
|
-
- img_url
|
|
106
|
-
- asset_url
|
|
107
|
-
- asset_img_url
|
|
108
|
-
- global_asset_url
|
|
109
|
-
- file_url
|
|
110
|
-
- file_img_url
|
|
111
|
-
- product_img_url
|
|
112
|
-
- collection_img_url
|
|
113
|
-
- article_img_url
|
|
114
|
-
- image_url
|
|
115
|
-
- preload_tag
|
|
116
|
-
JsonFilter:
|
|
117
|
-
- json
|
|
118
|
-
ColorFilter:
|
|
119
|
-
- color_mix
|
|
120
|
-
- color_contrast
|
|
121
|
-
- color_difference
|
|
122
|
-
- brightness_difference
|
|
123
|
-
- hex_to_rgba
|
|
124
|
-
- color_to_rgb
|
|
125
|
-
- color_to_hsl
|
|
126
|
-
- color_to_hex
|
|
127
|
-
- color_extract
|
|
128
|
-
- color_brightness
|
|
129
|
-
- color_modify
|
|
130
|
-
- color_lighten
|
|
131
|
-
- color_darken
|
|
132
|
-
- color_saturate
|
|
133
|
-
- color_desaturate
|
|
134
|
-
MoneyFilter:
|
|
135
|
-
- money
|
|
136
|
-
- money_with_currency
|
|
137
|
-
- money_without_currency
|
|
138
|
-
- money_without_trailing_zeros
|
|
139
|
-
StringFilter:
|
|
140
|
-
- md5
|
|
141
|
-
- camelcase
|
|
142
|
-
- format_code
|
|
143
|
-
- handle
|
|
144
|
-
- camelize
|
|
145
|
-
- handleize
|
|
146
|
-
- url_param_escape
|
|
147
|
-
- url_escape
|
|
148
|
-
- encode_url_component
|
|
149
|
-
CollectionFilter:
|
|
150
|
-
- sort_by
|
|
151
|
-
- within
|
|
152
|
-
- link_to_vendor
|
|
153
|
-
- link_to_type
|
|
154
|
-
- url_for_type
|
|
155
|
-
- url_for_vendor
|
|
156
|
-
TagFilter:
|
|
157
|
-
- link_to_tag
|
|
158
|
-
- highlight_active_tag
|
|
159
|
-
- link_to_add_tag
|
|
160
|
-
- link_to_remove_tag
|
|
161
|
-
CryptoFilter:
|
|
162
|
-
- hmac_sha1
|
|
163
|
-
- hmac_sha256
|
|
164
|
-
- md5
|
|
165
|
-
- sha1
|
|
166
|
-
- sha256
|
|
167
|
-
CustomerAccountFilter:
|
|
168
|
-
- customer_login_link
|
|
169
|
-
- customer_logout_link
|
|
170
|
-
- customer_register_link
|
|
171
|
-
- recover_password_link
|
|
172
|
-
- delete_customer_address_link
|
|
173
|
-
- edit_customer_address_link
|
|
174
|
-
- cancel_customer_order_link
|
|
175
|
-
CurrencyFormFilter:
|
|
176
|
-
- currency_selector
|
|
177
|
-
PaginationFilter:
|
|
178
|
-
- default_pagination
|
|
179
|
-
WeightFilter:
|
|
180
|
-
- unit
|
|
181
|
-
- weight
|
|
182
|
-
- weight_with_unit
|
|
183
|
-
TextFilter:
|
|
184
|
-
- pluralize
|
|
185
|
-
- highlight
|
|
186
|
-
- format_address
|
|
187
|
-
- paragraphize
|
|
188
|
-
- excerpt
|
|
189
|
-
- pad_spaces
|
|
190
|
-
FontFilter:
|
|
191
|
-
- font_face
|
|
192
|
-
- font_url
|
|
193
|
-
- font_modify
|
|
194
|
-
DistanceFilter:
|
|
195
|
-
- distance_from
|
|
196
|
-
MediaFilter:
|
|
197
|
-
- external_video_tag
|
|
198
|
-
- video_tag
|
|
199
|
-
- model_viewer_tag
|
|
200
|
-
- media_tag
|
|
201
|
-
- image_tag
|
|
202
|
-
- external_video_url
|
|
203
|
-
ThemeFilter:
|
|
204
|
-
- theme_url
|
|
205
|
-
- link_to_theme
|
|
206
|
-
- _online_store_editor_live_setting
|
|
207
|
-
MetafieldFilter:
|
|
208
|
-
- metafield_tag
|
|
209
|
-
- metafield_text
|
|
210
|
-
DebugFilter:
|
|
211
|
-
- debug
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
- additional_checkout_buttons
|
|
3
|
-
- address
|
|
4
|
-
- all_country_option_tags
|
|
5
|
-
- all_products
|
|
6
|
-
- article
|
|
7
|
-
- articles
|
|
8
|
-
- block
|
|
9
|
-
- blog
|
|
10
|
-
- blogs
|
|
11
|
-
- canonical_url
|
|
12
|
-
- cart
|
|
13
|
-
- checkout
|
|
14
|
-
- collection
|
|
15
|
-
- collections
|
|
16
|
-
- comment
|
|
17
|
-
- content_for_additional_checkout_buttons
|
|
18
|
-
- content_for_header
|
|
19
|
-
- content_for_index
|
|
20
|
-
- content_for_layout
|
|
21
|
-
- country_option_tags
|
|
22
|
-
- currency
|
|
23
|
-
- current_page
|
|
24
|
-
- current_tags
|
|
25
|
-
- customer
|
|
26
|
-
- customer_address
|
|
27
|
-
- discount_allocation
|
|
28
|
-
- discount_application
|
|
29
|
-
- external_video
|
|
30
|
-
- font
|
|
31
|
-
- forloop
|
|
32
|
-
- form
|
|
33
|
-
- fulfillment
|
|
34
|
-
- gift_card
|
|
35
|
-
- handle
|
|
36
|
-
- image
|
|
37
|
-
- images
|
|
38
|
-
- line_item
|
|
39
|
-
- link
|
|
40
|
-
- linklist
|
|
41
|
-
- linklists
|
|
42
|
-
- location
|
|
43
|
-
- localization
|
|
44
|
-
- metafield
|
|
45
|
-
- model
|
|
46
|
-
- model_source
|
|
47
|
-
- order
|
|
48
|
-
- page
|
|
49
|
-
- page_description
|
|
50
|
-
- page_image
|
|
51
|
-
- page_title
|
|
52
|
-
- pages
|
|
53
|
-
- paginate
|
|
54
|
-
- part
|
|
55
|
-
- policy
|
|
56
|
-
- powered_by_link
|
|
57
|
-
- predictive_search
|
|
58
|
-
- product
|
|
59
|
-
- product_option
|
|
60
|
-
- product_variant
|
|
61
|
-
- recommendations
|
|
62
|
-
- request
|
|
63
|
-
- routes
|
|
64
|
-
- script
|
|
65
|
-
- scripts
|
|
66
|
-
- search
|
|
67
|
-
- section
|
|
68
|
-
- selling_plan
|
|
69
|
-
- selling_plan_allocation
|
|
70
|
-
- selling_plan_group
|
|
71
|
-
- settings
|
|
72
|
-
- shipping_method
|
|
73
|
-
- shop
|
|
74
|
-
- shop_locale
|
|
75
|
-
- store_availability
|
|
76
|
-
- tablerow
|
|
77
|
-
- tax_line
|
|
78
|
-
- template
|
|
79
|
-
- theme
|
|
80
|
-
- transaction
|
|
81
|
-
- unit_price_measurement
|
|
82
|
-
- variant
|
|
83
|
-
- video
|
|
84
|
-
- video_source
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
- alternative_payment_methods
|
|
3
|
-
- breadcrumb
|
|
4
|
-
- checkout_html_classes
|
|
5
|
-
- checkout_scripts
|
|
6
|
-
- checkout_stylesheets
|
|
7
|
-
- content_for_footer
|
|
8
|
-
- content_for_logo
|
|
9
|
-
- content_for_order_summary
|
|
10
|
-
- direction
|
|
11
|
-
- locale
|
|
12
|
-
- order_summary_toggle
|
|
13
|
-
- page_title
|
|
14
|
-
- skip_to_content_link
|
|
15
|
-
- tracking_code
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
- assign
|
|
3
|
-
- break
|
|
4
|
-
- capture
|
|
5
|
-
- case: endcase
|
|
6
|
-
- comment: endcomment
|
|
7
|
-
- continue
|
|
8
|
-
- cycle
|
|
9
|
-
- decrement
|
|
10
|
-
- echo
|
|
11
|
-
- else
|
|
12
|
-
- elsif
|
|
13
|
-
- for: endfor
|
|
14
|
-
- form: endform
|
|
15
|
-
- if: endif
|
|
16
|
-
- ifchanged
|
|
17
|
-
- increment
|
|
18
|
-
- javascript: endjavascript
|
|
19
|
-
- layout
|
|
20
|
-
- liquid
|
|
21
|
-
- paginate: endpaginate
|
|
22
|
-
- raw
|
|
23
|
-
- render
|
|
24
|
-
- schema: endschema
|
|
25
|
-
- section
|
|
26
|
-
- style: endstyle
|
|
27
|
-
- stylesheet
|
|
28
|
-
- tablerow
|
|
29
|
-
- unless
|
|
30
|
-
- when
|