diff --git a/.changeset/fix-options-by-name-spaces.md b/.changeset/fix-options-by-name-spaces.md new file mode 100644 index 000000000..18a808747 --- /dev/null +++ b/.changeset/fix-options-by-name-spaces.md @@ -0,0 +1,5 @@ +--- +'@shopify/theme-check-common': patch +--- + +Fix loop argument validation for quoted `options_by_name` keys containing spaces. diff --git a/packages/theme-check-common/src/checks/liquid-html-syntax-error/checks/InvalidLoopArguments.spec.ts b/packages/theme-check-common/src/checks/liquid-html-syntax-error/checks/InvalidLoopArguments.spec.ts index 29bacff93..09f53bcb6 100644 --- a/packages/theme-check-common/src/checks/liquid-html-syntax-error/checks/InvalidLoopArguments.spec.ts +++ b/packages/theme-check-common/src/checks/liquid-html-syntax-error/checks/InvalidLoopArguments.spec.ts @@ -7,6 +7,8 @@ describe('detectInvalidLoopArguments', async () => { const testCases = [ `{% for i in array reversed %}{% endfor %}`, `{% for i in array reversed offset: 1 %}{% endfor %}`, + `{% for value in product.options_by_name['hello world'].values %}{% endfor %}`, + `{% for value in product.options_by_name["hello world"].values %}{% endfor %}`, `{% tablerow x in array limit: 10 %}{% endtablerow %}`, `{% tablerow x in array cols: 2 limit: 10 %}{% endtablerow %}`, ]; diff --git a/packages/theme-check-common/src/checks/liquid-html-syntax-error/checks/utils.ts b/packages/theme-check-common/src/checks/liquid-html-syntax-error/checks/utils.ts index 8ae1976fb..b4e2f5e8e 100644 --- a/packages/theme-check-common/src/checks/liquid-html-syntax-error/checks/utils.ts +++ b/packages/theme-check-common/src/checks/liquid-html-syntax-error/checks/utils.ts @@ -9,16 +9,15 @@ export function getValuesInMarkup(markup: string) { const DOUBLE_QUOTED_STRING = `"[^"]*"`; const SINGLE_QUOTED_STRING = `'[^']*'`; +const QUOTED_STRING = `(${DOUBLE_QUOTED_STRING}|${SINGLE_QUOTED_STRING})`; +const VARIABLE_LOOKUP_WITH_QUOTED_INDEX = `[^\\s,\\[]+(?:\\s*\\[\\s*${QUOTED_STRING}\\s*\\][^\\s,\\[]*)+`; // Lax parser does NOT complain about leading/trailing spaces inside ranges (e.g. `(1 .. 10 )`) and // within the parenthesis (e.g. `( 1 .. 10 )`), but fails to render the liquid when using the gem. // Strict parser does NOT complain, but still renders it. // To avoid any issues, we will remove extra spaces. const RANGE_MARKUP_COMPONENT_REGEX = `\\s*(-?\\d+(?:\\.\\d+)?|\\w+(?:\\.\\w+)*)\\s*`; const RANGE_MARKUP_REGEX = `\\(\\s*${RANGE_MARKUP_COMPONENT_REGEX}(\\.{2,})\\s*${RANGE_MARKUP_COMPONENT_REGEX}\\s*\\)`; -const REGULAR_TOKEN = `[^\\s,]+`; // tokens separated by commas or spaces - -// Quoted strings pattern (combination of double and single quoted) -const QUOTED_STRING = `(${DOUBLE_QUOTED_STRING}|${SINGLE_QUOTED_STRING})`; +const REGULAR_TOKEN = `(${VARIABLE_LOOKUP_WITH_QUOTED_INDEX}|[^\\s,]+)`; // tokens separated by commas or spaces // Value pattern for key-value pairs (can be quoted, parenthesized, or regular token) const VALUE_PATTERN = `(${QUOTED_STRING}|${RANGE_MARKUP_REGEX}|${REGULAR_TOKEN})`;