theme-check 0.4.0 → 0.5.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.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +6 -0
  3. data/CHANGELOG.md +10 -0
  4. data/CONTRIBUTING.md +5 -2
  5. data/README.md +9 -2
  6. data/RELEASING.md +1 -1
  7. data/config/default.yml +6 -0
  8. data/data/shopify_liquid/tags.yml +1 -0
  9. data/docs/checks/CHECK_DOCS_TEMPLATE.md +47 -0
  10. data/docs/checks/asset_size_javascript.md +79 -0
  11. data/docs/checks/convert_include_to_render.md +48 -0
  12. data/docs/checks/default_locale.md +46 -0
  13. data/docs/checks/deprecated_filter.md +46 -0
  14. data/docs/checks/liquid_tag.md +65 -0
  15. data/docs/checks/matching_schema_translations.md +93 -0
  16. data/docs/checks/matching_translations.md +72 -0
  17. data/docs/checks/missing_enable_comment.md +50 -0
  18. data/docs/checks/missing_required_template_files.md +26 -0
  19. data/docs/checks/missing_template.md +40 -0
  20. data/docs/checks/nested_snippet.md +69 -0
  21. data/docs/checks/parser_blocking_javascript.md +97 -0
  22. data/docs/checks/required_directories.md +25 -0
  23. data/docs/checks/required_layout_theme_object.md +28 -0
  24. data/docs/checks/space_inside_braces.md +63 -0
  25. data/docs/checks/syntax_error.md +49 -0
  26. data/docs/checks/template_length.md +50 -0
  27. data/docs/checks/translation_key_exists.md +63 -0
  28. data/docs/checks/undefined_object.md +53 -0
  29. data/docs/checks/unknown_filter.md +45 -0
  30. data/docs/checks/unused_assign.md +47 -0
  31. data/docs/checks/unused_snippet.md +32 -0
  32. data/docs/checks/valid_html_translation.md +53 -0
  33. data/docs/checks/valid_json.md +60 -0
  34. data/docs/checks/valid_schema.md +50 -0
  35. data/lib/theme_check.rb +3 -0
  36. data/lib/theme_check/asset_file.rb +34 -0
  37. data/lib/theme_check/check.rb +19 -9
  38. data/lib/theme_check/checks/asset_size_javascript.rb +74 -0
  39. data/lib/theme_check/checks/convert_include_to_render.rb +1 -1
  40. data/lib/theme_check/checks/default_locale.rb +1 -0
  41. data/lib/theme_check/checks/deprecated_filter.rb +1 -1
  42. data/lib/theme_check/checks/liquid_tag.rb +3 -3
  43. data/lib/theme_check/checks/matching_schema_translations.rb +1 -0
  44. data/lib/theme_check/checks/matching_translations.rb +1 -0
  45. data/lib/theme_check/checks/missing_enable_comment.rb +1 -0
  46. data/lib/theme_check/checks/missing_required_template_files.rb +1 -2
  47. data/lib/theme_check/checks/missing_template.rb +1 -0
  48. data/lib/theme_check/checks/nested_snippet.rb +1 -0
  49. data/lib/theme_check/checks/parser_blocking_javascript.rb +2 -1
  50. data/lib/theme_check/checks/required_directories.rb +1 -1
  51. data/lib/theme_check/checks/required_layout_theme_object.rb +1 -1
  52. data/lib/theme_check/checks/space_inside_braces.rb +1 -0
  53. data/lib/theme_check/checks/syntax_error.rb +1 -0
  54. data/lib/theme_check/checks/template_length.rb +1 -0
  55. data/lib/theme_check/checks/translation_key_exists.rb +1 -0
  56. data/lib/theme_check/checks/undefined_object.rb +10 -4
  57. data/lib/theme_check/checks/unknown_filter.rb +1 -0
  58. data/lib/theme_check/checks/unused_assign.rb +1 -0
  59. data/lib/theme_check/checks/unused_snippet.rb +1 -0
  60. data/lib/theme_check/checks/valid_html_translation.rb +1 -0
  61. data/lib/theme_check/checks/valid_json.rb +1 -0
  62. data/lib/theme_check/checks/valid_schema.rb +1 -0
  63. data/lib/theme_check/config.rb +2 -2
  64. data/lib/theme_check/language_server/completion_helper.rb +0 -10
  65. data/lib/theme_check/language_server/completion_provider.rb +1 -0
  66. data/lib/theme_check/language_server/handler.rb +11 -3
  67. data/lib/theme_check/language_server/server.rb +6 -1
  68. data/lib/theme_check/regex_helpers.rb +15 -0
  69. data/lib/theme_check/remote_asset_file.rb +44 -0
  70. data/lib/theme_check/theme.rb +7 -1
  71. data/lib/theme_check/version.rb +1 -1
  72. metadata +32 -2
@@ -0,0 +1,93 @@
1
+ # Spot errors in schema translations (`MatchingSchemaTranslations`)
2
+
3
+ Validates translations in schema tags (`{% schema %}`).
4
+
5
+ ## Check Details
6
+
7
+ Add checks for eliminating translations mistakes in schema tags.
8
+
9
+ :-1: Examples of **incorrect** code for this check:
10
+
11
+ ```liquid
12
+ {% comment %}
13
+ - fr.missing is missing
14
+ - fr.extra is not in the default locale
15
+ {% endcomment %}
16
+ {% schema %}
17
+ {
18
+ "locales": {
19
+ "en": {
20
+ "title": "Welcome",
21
+ "missing": "Product"
22
+ },
23
+ "fr": {
24
+ "title": "Bienvenue",
25
+ "extra": "Extra"
26
+ }
27
+ }
28
+ }
29
+ {% endschema %}
30
+
31
+ {% comment %}
32
+ - The French product label is missing.
33
+ {% endcomment %}
34
+ {% schema %}
35
+ {
36
+ "name": {
37
+ "en": "Hello",
38
+ "fr": "Bonjour"
39
+ },
40
+ "settings": [
41
+ {
42
+ "id": "product",
43
+ "label": {
44
+ "en": "Product"
45
+ }
46
+ }
47
+ ]
48
+ }
49
+ {% endschema %}
50
+ ```
51
+
52
+ :+1: Examples of **correct** code for this check:
53
+
54
+ ```liquid
55
+ {% schema %}
56
+ {
57
+ "name": {
58
+ "en": "Hello",
59
+ "fr": "Bonjour"
60
+ },
61
+ "settings": [
62
+ {
63
+ "id": "product",
64
+ "label": {
65
+ "en": "Product",
66
+ "fr": "Produit"
67
+ }
68
+ }
69
+ ]
70
+ }
71
+ {% endschema %}
72
+ ```
73
+
74
+ ## Check Options
75
+
76
+ The default configuration for this check is the following:
77
+
78
+ ```yaml
79
+ MatchingSchemaTranslations:
80
+ enabled: true
81
+ ```
82
+
83
+ ## Version
84
+
85
+ This check has been introduced in Theme Check 0.1.0.
86
+
87
+ ## Resources
88
+
89
+ - [Rule Source][codesource]
90
+ - [Documentation Source][docsource]
91
+
92
+ [codesource]: /lib/theme_check/checks/matching_schema_translations.rb
93
+ [docsource]: /docs/checks/matching_schema_translations.md
@@ -0,0 +1,72 @@
1
+ # Prevent mismatching translations (`MatchingTranslations`)
2
+
3
+ This check exists to prevent missing and superfluous translations in locale files.
4
+
5
+ ## Check Details
6
+
7
+ This check warns against missing translations in locale files.
8
+
9
+ :-1: Examples of **incorrect** code for this check:
10
+
11
+ ```js
12
+ // en.default.json
13
+ {
14
+ "greeting": "Hello, world",
15
+ "goodbye": "Bye, world"
16
+ }
17
+
18
+ // fr.json - missing `greeting` and `goodbye`
19
+ {
20
+ }
21
+
22
+ // fr.json - missing `greeting` and superfluous `goodby`
23
+ {
24
+ "greeting": "Bonjour, monde"
25
+ "goodby": "Au revoir, monde"
26
+ }
27
+ ```
28
+
29
+ :+1: Example of **correct** code for this check:
30
+
31
+ ```liquid
32
+ // en.default.json
33
+ {
34
+ "greeting": "Hello, world",
35
+ "goodbye": "Bye, world"
36
+ "pluralized_greeting": {
37
+ "one": "Hello, you",
38
+ "other": "Hello, y'all",
39
+ }
40
+ }
41
+
42
+ // fr.json
43
+ {
44
+ "greeting": "Bonjour, monde"
45
+ "goodbye": "Au revoir, monde"
46
+ "pluralized_greeting": {
47
+ "zero": "Je suis seul :(",
48
+ "few": "Salut, groupe!"
49
+ }
50
+ }
51
+ ```
52
+
53
+ ## Check Options
54
+
55
+ The default configuration for this check is the following:
56
+
57
+ ```yaml
58
+ MatchingTranslations:
59
+ enabled: true
60
+ ```
61
+
62
+ ## Version
63
+
64
+ This check has been introduced in Theme Check 0.1.0.
65
+
66
+ ## Resources
67
+
68
+ - [Rule Source][codesource]
69
+ - [Documentation Source][docsource]
70
+
71
+ [codesource]: /lib/theme_check/checks/matching_translations.rb
72
+ [docsource]: /docs/checks/matching_translations.md
@@ -0,0 +1,50 @@
1
+ # Prevent missing theme-check-enable comments (`MissingEnableComment`)
2
+
3
+ When `theme-check-disable` is used in the middle of a template, the corresponding `theme-check-enable` comment should also be included.
4
+
5
+ ## Check Details
6
+
7
+ This check aims at eliminating missing `theme-check-enable` comments.
8
+
9
+ :-1: Example of **incorrect** code for this check:
10
+
11
+ ```liquid
12
+ <!doctype html>
13
+ <html>
14
+ <head>
15
+ {% comment %}theme-check-disable ParserBlockingJavaScript{% endcomment %}
16
+ <script src="https://cdnjs.com/jquery.min.js"></script>
17
+ </head>
18
+ <body>
19
+ <!-- ... -->
20
+ </body>
21
+ </html>
22
+ ```
23
+
24
+ :+1: Example of **correct** code for this check:
25
+
26
+ ```liquid
27
+ <!doctype html>
28
+ <html>
29
+ <head>
30
+ {% comment %}theme-check-disable ParserBlockingJavaScript{% endcomment %}
31
+ <script src="https://cdnjs.com/jquery.min.js"></script>
32
+ {% comment %}theme-check-enable ParserBlockingJavaScript{% endcomment %}
33
+ </head>
34
+ <body>
35
+ <!-- ... -->
36
+ </body>
37
+ </html>
38
+ ```
39
+
40
+ ## Version
41
+
42
+ This check has been introduced in Theme Check 0.3.0.
43
+
44
+ ## Resources
45
+
46
+ - [Rule Source][codesource]
47
+ - [Documentation Source][docsource]
48
+
49
+ [codesource]: /lib/theme_check/checks/missing_enable_comment.rb
50
+ [docsource]: /docs/checks/missing_enable_comment.md
@@ -0,0 +1,26 @@
1
+ # Prevent missing required theme files (`MissingRequiredTemplateFiles`)
2
+
3
+ Makes sure all the required template files in a theme are present.
4
+
5
+ ## Check Options
6
+
7
+ The default configuration for this check is the following:
8
+
9
+ ```yaml
10
+ MissingRequiredTemplateFiles:
11
+ enabled: true
12
+ ```
13
+
14
+ ## Version
15
+
16
+ This check has been introduced in Theme Check 0.1.0.
17
+
18
+ ## Resources
19
+
20
+ - [Theme Requirements](https://shopify.dev/tutorials/review-theme-store-requirements-files)
21
+ - [Theme Templates](https://shopify.dev/docs/themes/theme-templates)
22
+ - [Rule Source][codesource]
23
+ - [Documentation Source][docsource]
24
+
25
+ [codesource]: /lib/theme_check/checks/missing_required_template_files.rb
26
+ [docsource]: /docs/checks/missing_required_template_files.md
@@ -0,0 +1,40 @@
1
+ # Prevent missing templates (`MissingTemplate`)
2
+
3
+ This check exists to prevent rendering resources with the `render` tag, `section` tag (and the deprecated `include` tag) that do not exist.
4
+
5
+ ## Check Details
6
+
7
+ This check is aimed at preventing liquid rendering errors.
8
+
9
+ :-1: Example of **incorrect** code for this check:
10
+
11
+ ```liquid
12
+ {% render 'snippet-that-does-not-exist' %}
13
+ ```
14
+
15
+ :+1: Example of **correct** code for this check:
16
+
17
+ ```liquid
18
+ {% render 'article-card' %}
19
+ ```
20
+
21
+ ## Check Options
22
+
23
+ The default configuration for this check is the following:
24
+
25
+ ```yaml
26
+ MissingTemplate:
27
+ enabled: true
28
+ ```
29
+
30
+ ## Version
31
+
32
+ This check has been introduced in Theme Check 0.1.0.
33
+
34
+ ## Resources
35
+
36
+ - [Rule Source][codesource]
37
+ - [Documentation Source][docsource]
38
+
39
+ [codesource]: /lib/theme_check/checks/missing_template.rb
40
+ [docsource]: /docs/checks/missing_template.md
@@ -0,0 +1,69 @@
1
+ # Prevent deeply nested snippets (`NestedSnippet`)
2
+
3
+ Reports deeply nested `render` tags (or deprecated `include` tags).
4
+
5
+ ## Check Details
6
+
7
+ This check is aimed at eliminating excessive nesting of snippets.
8
+
9
+ :-1: Examples of **incorrect** code for this check:
10
+
11
+ ```liquid
12
+ {% comment %}templates/index.liquid{% endcomment %}
13
+ {% render 'one' %}
14
+
15
+ {% comment %}snippets/one.liquid{% endcomment %}
16
+ {% render 'two' %}
17
+
18
+ {% comment %}snippets/two.liquid{% endcomment %}
19
+ {% render 'three' %}
20
+
21
+ {% comment %}snippets/three.liquid{% endcomment %}
22
+ {% render 'four' %}
23
+
24
+ {% comment %}snippets/four.liquid{% endcomment %}
25
+ ok
26
+ ```
27
+
28
+ :+1: Examples of **correct** code for this check:
29
+
30
+ ```liquid
31
+ {% comment %}templates/index.liquid{% endcomment %}
32
+ {% render 'one' %}
33
+
34
+ {% comment %}snippets/one.liquid{% endcomment %}
35
+ {% render 'two' %}
36
+
37
+ {% comment %}snippets/two.liquid{% endcomment %}
38
+ ok
39
+ ```
40
+
41
+ ## Check Options
42
+
43
+ The default configuration for this check is the following:
44
+
45
+ ```yaml
46
+ NestedSnippet:
47
+ enabled: true
48
+ max_nesting_level: 2
49
+ ```
50
+
51
+ ### `max_nesting_level`
52
+
53
+ The `max_nesting_level` option (Default: `2`) determines the maximum depth of snippets rendering snippets.
54
+
55
+ ## When Not To Use It
56
+
57
+ It's safe to disable this rule.
58
+
59
+ ## Version
60
+
61
+ This check has been introduced in Theme Check 0.1.0.
62
+
63
+ ## Resources
64
+
65
+ - [Rule Source][codesource]
66
+ - [Documentation Source][docsource]
67
+
68
+ [codesource]: /lib/theme_check/checks/nested_snippet.rb
69
+ [docsource]: /docs/checks/nested_snippet.md
@@ -0,0 +1,97 @@
1
+ # Discourage use of parser-blocking JavaScript (`ParserBlockingJavaScript`)
2
+
3
+ The `defer` or `async` attributes are extremely important on script tags. When neither of those attributes are used, a script tag will block the construction and rendering of the DOM until the script is _loaded_, _parsed_ and _executed_. It also creates congestion on the Network, messes with the resource priorities and significantly delays the rendering of the page.
4
+
5
+ Considering that JavaScript on Shopify themes should always be used to progressively _enhance_ the experience of the site, themes should never make use of parser-blocking script tags.
6
+
7
+ As a general rule, use `defer` if the order of execution matters, `async` otherwise. When in doubt, choose either one and get 80/20 of the benefits.
8
+
9
+ ## Check Details
10
+
11
+ This check is aimed at eliminating parser-blocking JavaScript on themes.
12
+
13
+ :-1: Examples of **incorrect** code for this check:
14
+
15
+ ```liquid
16
+ <!-- The script_tag filter outputs a parser-blocking script -->
17
+ {{ 'app-code.js' | asset_url | script_tag }}
18
+
19
+ <!-- jQuery is typically loaded synchronously because inline scripts depend on $, don't do that. -->
20
+ <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
21
+ ...
22
+ <button id="thing">Click me!</button>
23
+ <script>
24
+ $('#thing').click(() => {
25
+ alert('Oh. Hi Mark!');
26
+ });
27
+ </script>
28
+ ```
29
+
30
+ :+1: Examples of **correct** code for this check:
31
+
32
+ ```liquid
33
+ <!-- Good. Using the asset_url filter + defer -->
34
+ <script src="{{ 'theme.js' | asset_url }}" defer><script>
35
+
36
+ <!-- Also good. Using the asset_url filter + async -->
37
+ <script src="{{ 'theme.js' | asset_url }}" async><script>
38
+
39
+ <!-- Better than synchronous jQuery -->
40
+ <script src="https://code.jquery.com/jquery-3.6.0.min.js" defer><script>
41
+ ...
42
+ <button id="thing">Click me!</button>
43
+ <script>
44
+ // Because we're using `defer`, jQuery is guaranteed to
45
+ // be loaded when DOMContentLoaded fires. This technique
46
+ // could be used as a first step to refactor an old theme
47
+ // that inline depends on jQuery.
48
+ document.addEventListener('DOMContentLoaded', () => {
49
+ $('#thing').click(() => {
50
+ alert('Oh. Hi Mark!');
51
+ });
52
+ });
53
+ </script>
54
+
55
+ <!-- Even better. Web Native (no jQuery). -->
56
+ <button id="thing">Click Me</button>
57
+ <script>
58
+ const button = document.getElementById('thing');
59
+ button.addEventListener('click', () => {
60
+ alert('Oh. Hi Mark!');
61
+ });
62
+ </script>
63
+
64
+ <!-- Best -->
65
+ <script src="{{ 'theme.js' | asset_url }}" defer></script>
66
+ ...
67
+ <button id="thing">Click Me</button>
68
+ ```
69
+
70
+ ## Check Options
71
+
72
+ The default configuration for this check is the following:
73
+
74
+ ```yaml
75
+ ParserBlockingJavaScript:
76
+ enabled: true
77
+ ```
78
+
79
+ ## When Not To Use It
80
+
81
+ This should only be turned off with the `theme-check-disable` comment when there's no better way to accomplish what you're doing than with a parser-blocking script.
82
+
83
+ It is discouraged to turn this rule off.
84
+
85
+ ## Version
86
+
87
+ This check has been introduced in Theme Check 0.3.0.
88
+
89
+ ## Resources
90
+
91
+ - [Lighthouse Render-Blocking Resources Audit][render-blocking]
92
+ - [Rule Source][codesource]
93
+ - [Documentation Source][docsource]
94
+
95
+ [render-blocking]: https://web.dev/render-blocking-resources/
96
+ [codesource]: /lib/theme_check/checks/parser_blocking_javascript.rb
97
+ [docsource]: /docs/checks/parser_blocking_javascript.md