theme-check 1.13.0 → 1.14.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: 6510c266c71be36555ad42b3de0dc88db11710ac631dd2d7292175764b3ce51f
4
- data.tar.gz: d8eb627ff4f5de44cfea7a21049f37c42c007ff617fe2f07760ade8e1b0dc283
3
+ metadata.gz: b8c635ed30803cdeab5dfba7a7b65cbfabeaedf1d7c38bb0b99c35d1597798a4
4
+ data.tar.gz: 5abd13766f9f027aa6e5280120893380c6d845b230b0083d591701a5a9a31610
5
5
  SHA512:
6
- metadata.gz: 79f4683785b839a91731540fdf4b0e23d1d4f4a0a949aae3beb8637f651b8b0030ef5a3f9506da5de63109636410fc4cdb31616aade995442e61de43da4e2c55
7
- data.tar.gz: 5dda4447bb00c1b4f225255c628d9f5ab6c5e17c619065681631d68953e3b0b4562a523a3c359a5e566007de0042282aec775f82dcecd05e2c4c5b4c8eee0003
6
+ metadata.gz: c04023a0aa3c5de15038248e7f24fbaabcbe97a85fa67183006ddc59328d1e4641d490dad8f8643709d19259f91b01e3e996c23a0d03b951b59d3f35048e52ac
7
+ data.tar.gz: 81b5ad32a2fdcfa72ab07e47864616c5a2063ad9150ccc914d3a5b5863e09bc834d3497c78ac2d057a5645d3832dca0967c9fa425c661625fa9acf1c27c243d4
data/CHANGELOG.md CHANGED
@@ -1,4 +1,11 @@
1
1
 
2
+ v1.14.0 / 2023-01-10
3
+ ==================
4
+
5
+ * Add shopify-dev link to code completion suggestion title ([#700](https://github.com/Shopify/theme-check/issues/700))
6
+ * Fix examples in `SchemaJsonFormat` ([#698](https://github.com/Shopify/theme-check/issues/698))
7
+ * Do not suggest `escape` filter for already escaped strings ([#692](https://github.com/Shopify/theme-check/issues/692))
8
+
2
9
  v1.13.0 / 2023-01-04
3
10
  ==================
4
11
 
@@ -2657,7 +2657,7 @@
2657
2657
  "description": "",
2658
2658
  "syntax": "",
2659
2659
  "path": "/",
2660
- "raw_liquid": "{{ \"I hate it when I accidentally spill my duplication potion accidentally!\" | remove_first: ' accidentally' }}",
2660
+ "raw_liquid": "{{ \"I hate it when I accidentally spill my duplication potion accidentally!\" | remove_last: ' accidentally' }}",
2661
2661
  "parameter": false,
2662
2662
  "display_type": "text",
2663
2663
  "show_data_tab": true
@@ -3888,10 +3888,10 @@
3888
3888
  "examples": [
3889
3889
  {
3890
3890
  "name": "Basic types",
3891
- "description": "Most metafield types return a simple HTML element:\n\n| Type | Element | Attributes |\n| --- | --- | --- |\n| `boolean` | `<span>` | `class=\"metafield-boolean\"` |\n| `collection_reference` | `<a>` | `class=\"metafield-collection_reference\"` |\n| `color` | `<span>` | `class=\"metafield-color\"` |\n| `date` | `<time>` | `datetime=\"<the metafield value>\"`<br><br>`class=\"metafield-date\"`<br><br>Value is localized to the customer |\n| `date_time` | `<time>` | `datetime=\"<the metafield value>\"`<br><br>`class=\"metafield-date\"`<br><br>Value is localized to the customer |\n| `json` | `<script>` | `type=\"application/json\"`<br><br>`class=\"metafield-json\"` |\n| `money` | `<span>` | `class=\"metafield-money\"`<br><br>Value is formatted using the store's [HTML with currency setting](https://help.shopify.com/manual/payments/currency-formatting) |\n| `multi_line_text_field` | `<span>` | `class=\"metafield-multi_line_text_field\"` |\n| `number_decimal` | `<span>` | `class=\"metafield-number_decimal\"` |\n| `number_integer` | `<span>` | `class=\"metafield-number_integer\"` |\n| `page_reference` | `<a>` | `class=\"metafield-page_reference\"` |\n| `product_reference` | `<a>` | `class=\"metafield-page_reference\"` |\n| `rating` | `<span>` | `class=\"metafield-rating\"` | |\n| `single_line_text_field` | `<span>` | `class=\"metafield-single_line_text_field\"` |\n| `url` | `<a>` | `class=\"metafield-url\"` |\n| `variant_reference` | `<a>` | `class=\"metafield-variant_reference\"` |\n",
3891
+ "description": "Most metafield types return a simple HTML element:\n\n| Type | Element | Attributes |\n| --- | --- | --- |\n| `boolean` | `<span>` | `class=\"metafield-boolean\"` |\n| `collection_reference` | `<a>` | `class=\"metafield-collection_reference\"` |\n| `color` | `<span>` | `class=\"metafield-color\"` |\n| `date` | `<time>` | `datetime=\"<the metafield value>\"`<br><br>`class=\"metafield-date\"`<br><br>Value is localized to the customer |\n| `date_time` | `<time>` | `datetime=\"<the metafield value>\"`<br><br>`class=\"metafield-date\"`<br><br>Value is localized to the customer |\n| `json` | `<script>` | `type=\"application/json\"`<br><br>`class=\"metafield-json\"` |\n| `money` | `<span>` | `class=\"metafield-money\"`<br><br>Value is formatted using the store's [HTML with currency setting](https://help.shopify.com/manual/payments/currency-formatting) |\n| `multi_line_text_field` | `<span>` | `class=\"metafield-multi_line_text_field\"` |\n| `number_decimal` | `<span>` | `class=\"metafield-number_decimal\"` |\n| `number_integer` | `<span>` | `class=\"metafield-number_integer\"` |\n| `page_reference` | `<a>` | `class=\"metafield-page_reference\"` |\n| `product_reference` | `<a>` | `class=\"metafield-page_reference\"` |\n| `rating` | `<span>` | `class=\"metafield-rating\"` | |\n| `single_line_text_field` | `<span>` | `class=\"metafield-single_line_text_field\"` |\n| `url` | `<a>` | `class=\"metafield-url\"` |\n| `variant_reference` | `<a>` | `class=\"metafield-variant_reference\"` |\n| `rich_text_field` | <div> | `class=\"metafield-rich_text_field\"` |\n",
3892
3892
  "syntax": "",
3893
3893
  "path": "/products/health-potion",
3894
- "raw_liquid": "<!-- boolean -->\n{{ product.metafields.information.seasonal | metafield_tag }}\n\n<!-- collection_reference -->\n{{ product.metafields.information.related_collection | metafield_tag }}\n\n<!-- color -->\n{{ product.metafields.details.potion_color | metafield_tag }}\n\n<!-- date -->\n{{ product.metafields.information.expiry | metafield_tag }}\n\n<!-- date_time -->\n{{ product.metafields.information.brew_date | metafield_tag }}\n\n<!-- json -->\n{{ product.metafields.information.burn_temperature | metafield_tag }}\n\n<!-- money -->\n{{ product.metafields.details.price_per_ml | metafield_tag }}\n\n<!-- multi_line_text_field -->\n{{ product.metafields.information.shipping | metafield_tag }}\n\n<!-- number_decimal -->\n{{ product.metafields.information.salinity | metafield_tag }}\n\n<!-- number_integer -->\n{{ product.metafields.information.doses_per_day | metafield_tag }}\n\n<!-- page_reference -->\n{{ product.metafields.information.dosage | metafield_tag }}\n\n<!-- product_reference -->\n{{ product.metafields.information.related_product | metafield_tag }}\n\n<!-- rating -->\n{{ product.metafields.details.rating | metafield_tag }}\n\n<!-- single_line_text_field -->\n{{ product.metafields.information.directions | metafield_tag }}\n\n<!-- url -->\n{{ product.metafields.information.health | metafield_tag }}\n\n<!-- variant_reference -->\n{{ product.metafields.information.health | metafield_tag }}",
3894
+ "raw_liquid": "<!-- boolean -->\n{{ product.metafields.information.seasonal | metafield_tag }}\n\n<!-- collection_reference -->\n{{ product.metafields.information.related_collection | metafield_tag }}\n\n<!-- color -->\n{{ product.metafields.details.potion_color | metafield_tag }}\n\n<!-- date -->\n{{ product.metafields.information.expiry | metafield_tag }}\n\n<!-- date_time -->\n{{ product.metafields.information.brew_date | metafield_tag }}\n\n<!-- json -->\n{{ product.metafields.information.burn_temperature | metafield_tag }}\n\n<!-- money -->\n{{ product.metafields.details.price_per_ml | metafield_tag }}\n\n<!-- multi_line_text_field -->\n{{ product.metafields.information.shipping | metafield_tag }}\n\n<!-- number_decimal -->\n{{ product.metafields.information.salinity | metafield_tag }}\n\n<!-- number_integer -->\n{{ product.metafields.information.doses_per_day | metafield_tag }}\n\n<!-- page_reference -->\n{{ product.metafields.information.dosage | metafield_tag }}\n\n<!-- product_reference -->\n{{ product.metafields.information.related_product | metafield_tag }}\n\n<!-- rating -->\n{{ product.metafields.details.rating | metafield_tag }}\n\n<!-- single_line_text_field -->\n{{ product.metafields.information.directions | metafield_tag }}\n\n<!-- url -->\n{{ product.metafields.information.health | metafield_tag }}\n\n<!-- variant_reference -->\n{{ product.metafields.information.health | metafield_tag }}\n\n<!-- rich_text_field -->\n{{ product.metafields.information.health | metafield_tag }}",
3895
3895
  "parameter": false,
3896
3896
  "display_type": "text",
3897
3897
  "show_data_tab": false
@@ -3965,7 +3965,7 @@
3965
3965
  "category": "metafield",
3966
3966
  "deprecated": false,
3967
3967
  "deprecation_reason": "",
3968
- "description": "The following outlines the output for each metafield type:\n\n| Metafield type | Output |\n| --- | --- |\n| `single_line_text_field` | The metafield text |\n| `multi_line_text_field` | The metafield text |\n| `page_reference` | The page title |\n| `product_reference` | The product title |\n| `collection_reference` | The collection title |\n| `variant_reference` | The variant title |\n| `file_reference` | The file URL |\n| `number_integer` | The number |\n| `number_decimal` | The number |\n| `date` | The date |\n| `date-time` | The date and time |\n| `url` | The URL |\n| `json` | The JSON |\n| `boolean` | The boolean value |\n| `color` | The color value |\n| `weight` | The weight value and unit |\n| `volume` | The volume value and unit |\n| `dimension` | The dimension value and unit |\n| `rating` | The rating value |\n| `list.single_line_text_field` | The metafield values converted to a sentence.<br><br>For example, if you had the values `Toronto`, `Ottawa`, and `Vancouver`, then the output would be:<br><br>`Toronto, Ottawa, and Vancouver` |\n| `money` | The money value, formatted using the store's [**HTML with currency** setting](https://help.shopify.com/manual/payments/currency-formatting). |",
3968
+ "description": "The following outlines the output for each metafield type:\n\n| Metafield type | Output |\n| --- | --- |\n| `single_line_text_field` | The metafield text |\n| `multi_line_text_field` | The metafield text |\n| `page_reference` | The page title |\n| `product_reference` | The product title |\n| `collection_reference` | The collection title |\n| `variant_reference` | The variant title |\n| `file_reference` | The file URL |\n| `number_integer` | The number |\n| `number_decimal` | The number |\n| `date` | The date |\n| `date-time` | The date and time |\n| `url` | The URL |\n| `json` | The JSON |\n| `boolean` | The boolean value |\n| `color` | The color value |\n| `weight` | The weight value and unit |\n| `volume` | The volume value and unit |\n| `dimension` | The dimension value and unit |\n| `rating` | The rating value |\n| `list.single_line_text_field` | The metafield values converted to a sentence.<br><br>For example, if you had the values `Toronto`, `Ottawa`, and `Vancouver`, then the output would be:<br><br>`Toronto, Ottawa, and Vancouver` |\n| `money` | The money value, formatted using the store's [**HTML with currency** setting](https://help.shopify.com/manual/payments/currency-formatting). |\n| `rich_text_field` | The rich text value as simple text |",
3969
3969
  "parameters": [
3970
3970
 
3971
3971
  ],
@@ -11046,7 +11046,7 @@
11046
11046
  {
11047
11047
  "deprecated": false,
11048
11048
  "deprecation_reason": "",
11049
- "description": "> Note:\n> The selected variant is determined by the `variant` URL parameter. The `selected_variant` parameter is available on product pages only.\n\nFor a variant to be available, it needs to meet one of the following criteria:\n\n- The `variant.inventory_quantity` is greater than 1.\n- The `variant.inventory_policy` is set to `continue`.\n- The `variant.inventory_management` is `nil`.",
11049
+ "description": "> Note:\n> The selected variant is determined by the `variant` URL parameter. The `selected_variant` parameter is available on product pages only.\n\nFor a variant to be available, it needs to meet one of the following criteria:\n\n- The `variant.inventory_quantity` is greater than 0.\n- The `variant.inventory_policy` is set to `continue`.\n- The `variant.inventory_management` is `nil`.",
11050
11050
  "examples": [
11051
11051
 
11052
11052
  ],
@@ -11100,7 +11100,7 @@
11100
11100
  {
11101
11101
  "deprecated": false,
11102
11102
  "deprecation_reason": "",
11103
- "description": "For a variant to be available, it needs to meet one of the following criteria:\n\n- The `variant.inventory_quantity` is greater than 1.\n- The `variant.inventory_policy` is set to `continue`.\n- The `variant.inventory_management` is `nil`.",
11103
+ "description": "For a variant to be available, it needs to meet one of the following criteria:\n\n- The `variant.inventory_quantity` is greater than 0.\n- The `variant.inventory_policy` is set to `continue`.\n- The `variant.inventory_management` is `nil`.",
11104
11104
  "examples": [
11105
11105
 
11106
11106
  ],
@@ -11118,7 +11118,7 @@
11118
11118
  {
11119
11119
  "deprecated": false,
11120
11120
  "deprecation_reason": "",
11121
- "description": "For a variant to be available, it needs to meet one of the following criteria:\n\n- The `variant.inventory_quantity` is greater than 1.\n- The `variant.inventory_policy` is set to `continue`.\n- The `variant.inventory_management` is `nil`.",
11121
+ "description": "For a variant to be available, it needs to meet one of the following criteria:\n\n- The `variant.inventory_quantity` is greater than 0.\n- The `variant.inventory_policy` is set to `continue`.\n- The `variant.inventory_management` is `nil`.",
11122
11122
  "examples": [
11123
11123
 
11124
11124
  ],
@@ -18513,7 +18513,13 @@
18513
18513
  "type": "string",
18514
18514
  "name": "",
18515
18515
  "description": "",
18516
- "array_value": ""
18516
+ "array_value": "",
18517
+ "denied_filters": [
18518
+ "escape",
18519
+ "escape_once",
18520
+ "url_escape",
18521
+ "url_param_escape"
18522
+ ]
18517
18523
  }
18518
18524
  ]
18519
18525
  },
@@ -18583,7 +18589,13 @@
18583
18589
  "type": "string",
18584
18590
  "name": "",
18585
18591
  "description": "",
18586
- "array_value": ""
18592
+ "array_value": "",
18593
+ "denied_filters": [
18594
+ "escape",
18595
+ "escape_once",
18596
+ "url_escape",
18597
+ "url_param_escape"
18598
+ ]
18587
18599
  }
18588
18600
  ]
18589
18601
  },
@@ -19,7 +19,7 @@ The following examples contain code snippets that either fail or pass this check
19
19
  "en": {
20
20
  "title": "Welcome", "product": "Product"
21
21
  },
22
- "fr": { "title": "Bienvenue", "produit": "Produit" }
22
+ "fr": { "title": "Bienvenue", "product": "Produit" }
23
23
  }
24
24
  }
25
25
  {% endschema %}
@@ -33,11 +33,11 @@ The following examples contain code snippets that either fail or pass this check
33
33
  "locales": {
34
34
  "en": {
35
35
  "title": "Welcome",
36
- "missing": "Product"
36
+ "product": "Product"
37
37
  },
38
38
  "fr": {
39
39
  "title": "Bienvenue",
40
- "missing": "TODO"
40
+ "product": "Produit"
41
41
  }
42
42
  }
43
43
  }
@@ -15,8 +15,10 @@ module ThemeCheck
15
15
  return [] unless can_complete?(content, cursor)
16
16
 
17
17
  context = context_with_cursor_before_potential_filter_separator(context)
18
- available_filters_for(determine_input_type(context))
19
- .select { |w| w.name.start_with?(partial(content, cursor)) }
18
+ variable_lookup = VariableLookupFinder.lookup(context)
19
+ denied_filters = denied_filters_for(variable_lookup)
20
+ available_filters_for(determine_input_type(variable_lookup))
21
+ .select { |filter| filter.name.start_with?(partial(content, cursor)) && denied_filters.none?(filter.name) }
20
22
  .map { |filter| filter_to_completion(filter) }
21
23
  end
22
24
 
@@ -38,14 +40,18 @@ module ThemeCheck
38
40
  context.clone_and_overwrite(col: context.col + diff)
39
41
  end
40
42
 
41
- def determine_input_type(context)
42
- variable_lookup = VariableLookupFinder.lookup(context)
43
+ def determine_input_type(variable_lookup)
44
+ return if variable_lookup.nil?
43
45
 
44
- if variable_lookup
45
- object, property = VariableLookupTraverser.lookup_object_and_property(variable_lookup)
46
- return property.return_type if property
47
- return object.name if object
48
- end
46
+ object, property = VariableLookupTraverser.lookup_object_and_property(variable_lookup)
47
+ return property.return_type if property
48
+ return object.name if object
49
+ end
50
+
51
+ def denied_filters_for(variable_lookup)
52
+ return [] if variable_lookup.nil?
53
+
54
+ VariableLookupTraverser.find_object(variable_lookup.name).denied_filters
49
55
  end
50
56
 
51
57
  def available_filters_for(input_type)
@@ -16,7 +16,7 @@ module ThemeCheck
16
16
  private
17
17
 
18
18
  def title(entry)
19
- "### #{entry.name}"
19
+ "### [#{entry.name}](#{entry.shopify_dev_url})"
20
20
  end
21
21
 
22
22
  def body(entry)
@@ -10,7 +10,9 @@ module ThemeCheck
10
10
 
11
11
  attr_reader :hash
12
12
 
13
- def_delegators :return_type_instance, :generic_type?, :array_type?, :array_type, :to_s
13
+ def_delegators :return_type_instance, :generic_type?, :array_type?, :array_type, :to_s, :denied_filters
14
+
15
+ SHOPIFY_DEV_ROOT_URL = "https://shopify.dev/api/liquid"
14
16
 
15
17
  def initialize(hash = {})
16
18
  @hash = hash || {}
@@ -39,6 +41,10 @@ module ThemeCheck
39
41
  hash['deprecation_reason'] || nil
40
42
  end
41
43
 
44
+ def shopify_dev_url
45
+ SHOPIFY_DEV_ROOT_URL
46
+ end
47
+
42
48
  attr_writer :return_type
43
49
 
44
50
  def return_type
@@ -10,7 +10,11 @@ module ThemeCheck
10
10
  end
11
11
 
12
12
  def input_type
13
- hash['syntax'].split(' | ')[0]
13
+ @input_type ||= hash['syntax'].split(' | ')[0]
14
+ end
15
+
16
+ def shopify_dev_url
17
+ "#{SHOPIFY_DEV_ROOT_URL}/filters/#{hash['name']}"
14
18
  end
15
19
  end
16
20
  end
@@ -6,7 +6,13 @@ module ThemeCheck
6
6
  class ObjectEntry < BaseEntry
7
7
  def properties
8
8
  (hash['properties'] || [])
9
- .map { |hash| PropertyEntry.new(hash) }
9
+ .map do |prop_hash|
10
+ PropertyEntry.new(prop_hash, hash['name'])
11
+ end
12
+ end
13
+
14
+ def shopify_dev_url
15
+ "#{SHOPIFY_DEV_ROOT_URL}/objects/#{hash['name']}"
10
16
  end
11
17
  end
12
18
  end
@@ -8,6 +8,10 @@ module ThemeCheck
8
8
  nil
9
9
  end
10
10
 
11
+ def shopify_dev_url
12
+ "#{SHOPIFY_DEV_ROOT_URL}/filters/#{hash['name']}"
13
+ end
14
+
11
15
  private
12
16
 
13
17
  def return_type_hash
@@ -3,7 +3,19 @@
3
3
  module ThemeCheck
4
4
  module ShopifyLiquid
5
5
  class SourceIndex
6
- class PropertyEntry < BaseEntry; end
6
+ class PropertyEntry < BaseEntry
7
+ attr_reader :parent_name
8
+
9
+ def initialize(hash, parent_name)
10
+ @hash = hash || {}
11
+ @return_type = nil
12
+ @parent_name = parent_name
13
+ end
14
+
15
+ def shopify_dev_url
16
+ "#{SHOPIFY_DEV_ROOT_URL}/objects/#{parent_name}##{parent_name}-#{hash['name']}"
17
+ end
18
+ end
7
19
  end
8
20
  end
9
21
  end
@@ -24,6 +24,10 @@ module ThemeCheck
24
24
  hash['array_value']
25
25
  end
26
26
 
27
+ def denied_filters
28
+ hash['denied_filters'] || []
29
+ end
30
+
27
31
  private
28
32
 
29
33
  def return_type_hash
@@ -14,6 +14,10 @@ module ThemeCheck
14
14
  'type' => "tag<#{name}>",
15
15
  }
16
16
  end
17
+
18
+ def shopify_dev_url
19
+ "#{SHOPIFY_DEV_ROOT_URL}/tags/#{hash['name']}"
20
+ end
17
21
  end
18
22
  end
19
23
  end
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module ThemeCheck
3
- VERSION = "1.13.0"
3
+ VERSION = "1.14.0"
4
4
  end
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.13.0
4
+ version: 1.14.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: 2023-01-04 00:00:00.000000000 Z
11
+ date: 2023-01-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: liquid