- 841ca6d1: Update repository URL for all packages to be case sensitive
- Updated dependencies [841ca6d1]
- @shopify/[email protected]
- c85a6131: Cache liquidDoc fetch results
- 913d5386: Add unique settings ID validator to prevent duplicate IDs in theme configurations
- 931dc9b9: Add hover support for Liquid snippets using {% doc %} annotations
- Updated dependencies [dd0cd4d2]
- @shopify/[email protected]
- Updated dependencies [ac55577a]
- @shopify/[email protected]
- b31e0f85: [internal] Add
offset
information on Schema objects - 34c2268a: This update ensures that the AppBlockMissingSchema theme check will only run on block files on theme app extensions, to avoid errors surfacing when the theme check is incorrectly run on snippets. Renamed the check to make it more accurate (from MissingSchema to AppBlockMissingSchema).
- c74850c8: [Internal] Add template type interfaces
- c60e61ba: [Internal] Add schema raw value to schema node
- d7436b4a: Add
JsonMissingBlock
check - 6f1862c8: Add
SchemaPresetsStaticBlocks
check - d01e657b: [Internal] Add JSONC support to the AST parser
- 8e909870: Import fix for PropertyNode in JSONMissingBlock.
- 8912fab8: Update Ohm grammar for ContentFor tag to extract arguments correctly Update ValidContentForArguments check to report deprecated context. argument usage
- 51ec6a7a: Add case to
SchemaPresetBlockOrder
check
- Updated dependencies [8912fab8]
- @shopify/[email protected]
- 05ae5ea8: Added
MissingSchema
theme check to identify missing schemas in theme app extensions. - 26215724: Add
EmptyBlockContent
Check - 73758ba1: Add
LiquidFreeSettings
check - 5e8a2bfe: Add
SchemaPresetsBlockOrder
check
- 05b928ea: [internal] Rejig how we do JSON completion & Hover
- a579d59e: (internal) Fixup bug in nodeAtPath
- d2b5942a: Add positional attribute to exported Parameter type
- 3e69d732: Update theme check urls
- 1083b2bc: Refactor
ValidBlockTarget
andValidLocalBlocks
. - 5a2caaee: Import
Section
andThemeBlock
types. - Updated dependencies [1f54be13]
- @shopify/[email protected]
- 16e2f37: Temporarily disable ValidLocalBlocks
- 4a18a78: Temporarily disable ValidBlockTarget
- 3f7680e: Add the
ValidBlockTarget
Check - 8a0bf78: Add the
ValidLocalBlocks
Check - c4813ff: Add the
BlockIdUsage
check - 7317830: Add translation checking to
ValidSchemaName
check - add2445: [Internal] Add better building blocks for dealing with
{% schema %}
content
- 7a6dfe8: Fix weird root URI loading bug
- b558bfe: Fixup
CaptureOnContentForBlock
check - 9a07208: [Bug fix] Metafield definitions should use
namespace.key
for auto-completion - f09c923: Moving internal methods around
- Updated dependencies [c4813ff]
- @shopify/[email protected]
-
b431db7: Add
ValidateSchemaName
check -
568d53b: Add the
ValidContentForArguments
check -
6014dfd: Support metafield auto-completion based on .shopify/metafields.json file
- The metafield definitions can be fetched from Admin API
- The format of the JSON needs to be the following:
{ "<definition_group>": [ { "name": "...", "namespace": "...", "description": "...", "type": { "category": "...", "name": "..." }, }, ... ], ... }
The definition group needs to be one of the following:
- 'article'
- 'blog'
- 'brand'
- 'collection'
- 'company'
- 'company_location'
- 'location'
- 'market'
- 'order'
- 'page'
- 'product'
- 'variant'
- 'shop'
- Updated dependencies [568d53b]
- @shopify/[email protected]
-
4b574c1: [Breaking] Replace absolute path concerns with URIs
This implies a couple of changes:
Config
now holds arootUri
instead ofroot
path.loadConfig
injections needs to change their return value accordingly- In checks,
- The context helper
absolutePath
has been replaced bytoUri
- The context helper
relativePath
has been replaced bytoRelativePath
- The context helper
SourceCode
objects now hold auri
instead of apath
toSourceCode
now accepts auri
instead of apath
-
4b574c1: [Breaking] Replace fs-based dependency injections with AbstractFileSystem injection
runChecks(theme, { - getDefaultTranslations, - getDefaultLocale, - getDefaultSchemaLocale, - getDefaultSchemaTranslations, - fileExists, - fileSize, + fs: new FileSystemImpl(), themeDocset, jsonValidationSet, })
- 5fab0e9: (Internal) Add path.basename util
- Updated dependencies [c664d52]
- @shopify/[email protected]
- Updated dependencies [1c73710]
- Updated dependencies [d1f9fef]
- Updated dependencies [70e2241]
- @shopify/[email protected]
- 457f9cb: Add CaptureOnContentForBlock check
- edb7f2e: Standardized variable number formatting
- bb79d83: Add VariableName check
- ff78229: Update 'theme-check-common/src/json.ts' to use 'jsonc-parser'
- ec1fbd7: The comment object should be available to section files
-
03b41e1: Breaking:
jsonValidationSet
's schemas public API changeNow takes a function of the following signature:
interface JsonValidationSet = { schemas: (context: 'theme' | 'app') => Promise<SchemaDefinition[]> }
Reason being we want to support
fileMatch
overloading ofblocks/*.liquid
files and we needed a way to identify which context you're in.Unfortunately, the JSON schema for
blocks/*.liquid
files in theme app extensions isn't the same one we have in themes. There doesn't seem to be a way to unify them either. -
03b41e1: Theme Check Config files now accept the
context
propertyIn your
.theme-check.yml
files, you can set thecontext
property totheme
orapp
. By default, it'stheme
. Thetheme-check:theme-app-extension
config sets it toapp
.You shouldn't need to care about this. It's there so we can do contextual things internally.
-
03b41e1: Add support for the schemas manifest on Shopify/theme-liquid-docs
Shopify/theme-liquid-docs now supports composable JSON schemas (with relative paths). To solve the
blocks/*.liquid
file match JSON schema overload depending on the context (app
ortheme
), we defined two manifests that describe the schemas required by your solution and define the fileMatch rules:@shopify/theme-check-docs-updater
now reads those manifests and downloads the tree of dependency that they require. We will no longer need to make new theme-tools releases whenever we add new schemas. We'll be able to dev them and their file associations directly from Shopify/theme-liquid-docs and have downstream consumers updated automatically (the same way docs are automatically updated).
-
767d223: Add
ValidJSON
checkThis check validates JSON files against the JSON schemas provided in the
jsonValidationSet
provided there is a file match. -
767d223: Breaking: Redesign
jsonValidationSet
public API(Only breaking for in-browser packages, node packages are still batteries-included)
Before:
type JsonValidationSet = { sectionSchema(): Promise<string>; translationSchema(): Promise<string>; validateSectionSchema(): Promise<ValidateFunction>; };
After:
type URI = string; type SchemaDefinition = { uri: string; fileMatch?: string[]; schema: Promise<string>; }; type JsonValidationSet = { schemas: SchemaDefinition[]; };
We’re getting rid of ajv and we’ll use vscode-json-languageservice in Theme Check instead. That dependency is required by the language server anyway, might as well reuse it instead of depending on a totally different solution for validation. We'll also get better reporting of Syntax Errors because the parser used by
vscode-json-languageservice
is better.Moreover, this new design leaves space for
$ref
support.
-
8e3c7e2: Add Schema translation checking to
MatchingTranslations
-
8e3c7e2: Breaking: add
getDefaultSchema{Locale,Translations}(Factory)?
dependenciesTo be used to power
MatchingTranslations
for Schema translations.To be used to power Schema translations code completion and hover in section and theme block
{% schema %}
JSON blobs.
- 8e3c7e2: Unify parseJSON usage
- 8710bde: Fix AssetAppBlock{CSS,JavaScript} bug when cwd != project root
-
042f1e0: Breaking: internal rename of
schemaValidators
tojsonValidationSet
This breaks the browser dependencies public API (for
startServer
andrunChecks
) and will thus require some code changes in those contexts.The node packages absorb the dependency injection and are not breaking.
-
a9ae65f: Add Language Server and Theme Check support for checkout.liquid objects
- 0990c47: Fix config validation problem that required optional settings
- 617b766: Add parser support for trailing commas at the end of Liquid tags and filters
- Updated dependencies [0990c47]
- Updated dependencies [617b766]
- @shopify/[email protected]
- Fix parsing of
}}
inside{% %}
and vice-versa - 8f19b87: Bump lodash deps
-
8451075: Theme Check 2.0
Our official release of the next iteration of Theme Check, the linter for Shopify themes.
What is is: A TypeScript rewrite of Theme Check.
But... why? A couple of reasons:
- To lint Liquid files, we prefer one Abstract Syntax Tree (AST) per file. Not one Liquid AST and one HTML AST.
- Theme Check Ruby had weird duplicated checks because of that (such as
ParserBlockingJavaScript
andParserBlockingScriptTag
) - For that we reused the
@shopify/liquid-html-parser
we wrote for the prettier plugin. - One tree, two languages.
- Theme Check Ruby had weird duplicated checks because of that (such as
- We wanted to run the linter in the Online Store Code Editor and—unlike WASM or WebSockets—there is no overhead or latency cost to running a TypeScript-based Language Server in a Web Worker.
- Theme developers are Front End developers. If we were to make a Venn diagram, we'd observe that the intersection of Ruby and Theme developers is much smaller than that of JavaScript and Theme developers.
- This makes the TypeScript codebase easier to contribute to.
- This makes the plugin ecosystem more accessible (you're more likely to have a
package.json
file in a theme than aGemfile
).
- The
@shopify/cli
was rewritten in TypeScript. This made the Ruby integration very problematic.- Windows performance was terrible
- Installation setup was weird, often problematic and complicated
- The VS Code extension required a secondary installation step, and thus lost the ability to automatically self-update
With the move to TypeScript, we believe that it will make it easier for us to ship more robust features faster.
- To lint Liquid files, we prefer one Abstract Syntax Tree (AST) per file. Not one Liquid AST and one HTML AST.
- 8451075:
package.json
and README cleanups - Updated dependencies [8451075]
- @shopify/[email protected]
- 636895f: Make LiquidHTMLSyntaxError more tolerant to unclosed nodes in branching code
- aeb9b3f: Add
UnclosedHTMLElement
check
- Updated dependencies [636895f]
- Updated dependencies [636895f]
- @shopify/[email protected]
- 772a1ce: Update
translation-key-exists
check and intelligent code completion to always stay up-to-date with Shopify translation keys
-
b05a6a8: Add support for the following Language Server configurations:
themeCheck.checkOnOpen
themeCheck.checkOnSave
themeCheck.checkOnChange
This is mostly for backward compatibility and to not be annoying :)
- 79b0549: Add
app
object support for theme app extensions - ac1deb4: Improved message reporting for
AssetSize*
checks
- Updated dependencies [78813ea]
- @shopify/[email protected]
- d9f3063: Do not report UnusedAssign for variables starting with an underscore
- fe54680: Fix
MissingAsset
false positives for .css.liquid, .js.liquid and .scss.liquid files - e00c319: Fix false ParserBlockingScript reports for scripts of type module
- aa33c5f: Fix hover, completion and
UndefinedObject
reporting of{% increment var %}
and{% decrement var %}
- 0d71145: Fix UnusedAssign false positives in raw-like nodes
- Updated dependencies [0d71145]
- @shopify/[email protected]
- 96d4d5e: Re-add
ignoreMissing
support toMissingTemplate
- dacdd9f: Add blocks/ files contextual completion, hover and UndefinedObject support
-
2cf7a11: Rename and alias a couple of checks
DeprecatedFilters
->DeprecatedFilter
DeprecatedTags
->DeprecatedTag
- Alias
LiquidHTMLSyntaxError
withSyntaxError
andHtmlParsingError
- Alias
ParserBlockingJavaScript
withParserBlockingScriptTag
- Alias
JSONSyntaxError
withValidJson
- Alias
AssetSizeCSS
withAssetSizeCSSStylesheetTag
- Alias
RemoteAsset
withAssetUrlFilters
-
2cf7a11: Add support for aliases in check configs
- 8d35241: Fix
paginate
object completion, hover andUndefinedObject
reporting - 201f30c: Add support for
{% layout none %}
- c0298e7: Fix
recommendations
completion, hover andUndefinedObject
reporting - 6fad756: Fix
predictive_search
completion, hover andUndefinedObject
reporting - fc86c91: Fix
form
object completion, hover andUndefinedObject
reporting
- 279a464: Replace
AssetUrlFilters
withRemoteAsset
- d71a5e2: Fix completion, hover and UndefinedObject reporting of tablerowloop and forloop variables
- 6c2c00f:
UndefinedObject
should not show any offenses when themeDocset is not given - f1a642f: Improve resilience of theme check pipeline by preventing entire failure if an individual check fails
- b7514f4: Fixup UndefinedObject for sections
- beeb85f: Introduce 'UndefinedObject' check
- a05aebb: Add
AssetSizeJavascript
check
- 14b9ee2: Fixup package.json configs
- 441a8c5: Remove
ImgLazyLoading
- 972c26c: Introduce 'DeprecatedFilters' check (+ suggestions)
- 25b79f0: Rename LiquidDrop -> LiquidVariableLookup
- 12c794a: Add
DeprecatedTags
check
- c00e929: Bug fix for
AssetSizeCSS
: Fixes redundant messages. - f3cda64: Fixup AppBlock*Checks to not throw errors on missing property
- b1b8366: Fixup AssetUrlFilters node targeting
- c00e929: Bug fix for
AssetSizeAppBlockCSS
: Corrects underlining issues. - c00e929: Bug fix for
AssetUrlFilters
: Reports better messaging. - b1b8366: Fix RequireThemeObject highlighting
- b1b8366: Fix the recommended and severity values
- c00e929: Bug fix for
AssetSizeAppBlockJavascript
: Corrects underlining issues. - Updated dependencies [02f4731]
- @shopify/[email protected]
- Patch bump because it depends on @shopify/prettier-plugin-liquid
- Updated dependencies [5479a63]
- Updated dependencies [5479a63]
- @shopify/[email protected]
- 5ba20bd: Fixed bug for
AssetUrlFilters
check - 5ba20bd: Add
ContentForHeaderModification
check - 5ba20bd: Add
AssetSizeCSS
check - 5ba20bd: Add
AssetSizeAppBlockJavascript
check - 5ba20bd: Add
AssetSizeAppBlockCSS
check
- 2e73166: Fix the
DocsetEntry
types to better match the theme-liquid-docs json files
- e67a16d: Breaking: Dependency injected json schema validators
- 4db7c7e: Add
UnknownFilter
check - a94f23c: Bump prettier-plugin-liquid to v1.2.1
-
b3ed3b9: Add
ValidSchema
check -
d19500f: Add
AppBlockValidTags
check -
8e76424: Add support for
.theme-check.yml
config filesNew features:
-
Developers can write their own checks and publish them to npm
Modules that follow the
@scope/theme-check-*
ortheme-check-*
naming conventions are automatically loaded.The
require
property of the configuration file can be used to load checks that do not follow the naming convention.See Creating a Theme Check extension for more info.
-
extends
can be an array -
extends
can refer to node module dependencies -
extends
also accepts "modern" config identifiers:theme-check:all
for all the checks and with default settingstheme-check:recommended
for the recommended checks and settingstheme-check:theme-app-extension
for theme app extensions
Removed features:
include_categories: []
exclude_categories: []
Replaced features:
require: []
this can be used to load unconventional (or private)theme-check-js
checks. Ruby checks are not supported.
Breaking changes:
-
Custom checks written in Ruby won't work Theme Check in TypeScript
-
The
*
(star) glob inignore
configurations does not capture the forward slash (/
) unless at the end of the pattern.Fix: replace
*
by**
.This comes from a difference between how
minimatch
and Ruby handles file globs.
Extra care has been placed to make the transition as smooth as possible.
-
-
3096e53: Add
ValidHTMLTranslation
check -
daf5189: Add
AssetPreload
check -
6fb9db9: Add
ImgLazyLoading
check
- 2f0f941: Add
MissingAsset
check - fd3fc3c: Add
AssetUrlFilters
- 5ae97c9: Add
PaginationSize
check - 85cf8f3: Add
CdnPreconnect
- 051aff1: Introduce
ThemeDocset
andThemeSchemas
dependencies to support core checks
- Bump prettier-plugin-liquid to v1.1.0
- 502bad8: Add documentation URLs to checks
-
cad8e17: Introduce API for schema definition
New: The
meta.schema
property ofCheckDefinition
s accept a key-value pair ofSchemaProp
.const schema = { myNumberSetting: SchemaProp.number(10), myStringSetting: SchemaProp.string('default'), myStringArraySetting: SchemaProp.array<string>(['default', 'value']), myBooleanSetting: SchemaProp.boolean(true), myObjectSetting: SchemaProp.object({ age: SchemaProp.number(), name: SchemaProp.string(), company: SchemaProp.object({ name: SchemaProp.string(), }).optional(), }), }; // `<typeof schema>` is required to type `context.settings`. export const SomeCheck: LiquidCheckDefinition<typeof schema> = { meta: { code: '...', name: '...', docs: { /* ... */ }, type: SourceCodeType.LiquidHtml, severity: Severity.ERROR, schema, targets: [], }, create(context) { context.settings.severity; // typed as Severity context.settings.myNumberSetting; // typed as number context.settings.myBooleanSetting; // typed as boolean context.settings.myStringSetting; // typed as string context.settings.myStringArraySetting; // typed as string[] context.settings.myObjectSetting.age; // typed as number | undefined context.settings.myObjectSetting.name; // typed as string context.settings.myObjectSetting.company?.name; // typed as string | undefined return {}; }, };
-
9e99728: Add
UnusedAssign
-
f99c896: Add
LiquidHTMLSyntaxError
-
e0c131a: Add
JSONSyntaxError
-
e0c131a: Breaking:
SourceCode
can takeast: AST[T] | Error
, whereError
is a parsing error -
ccd5146: Add
DeprecatedLazysizes
-
c715fbe: Add
ImgWidthAndHeight
-
9e99728: Add
RequiredLayoutThemeObject
-
edd8925: Add
DeprecateBgsizes
- 9d3d557: Fix RequiredLayoutThemeObject bugs
- 60c92be: Fix unhandled TranslationKeyExists error
-
71e6b44: Add support for fixes and suggestions
New:
context.report
now accepts two new properties:-
fix: Fixer
, accepts a callback that is given a corrector and produces transformations that are deemed safe to apply without confirmation on the initial document.- JSON checks will receive a
JSONCorrector
(API) - LiquidHTML checks will receive a
StringCorrector
(API)
type Fixer<S> = (corrector: Corrector<S>) => void;
- JSON checks will receive a
-
suggest: Suggestion[]
, accepts an array of Suggestion. Those are like fixes but are not considered safe either because there's multiple ways to fix the problem or because the change requires care.type Suggestion<S> = { message: String; fix: Fixer<S>; };
Example usage:
// A safe change, add a "TODO" translation key context.report({ message: `The translation for '${path}' is missing`, startIndex: closest.loc!.start.offset, endIndex: closest.loc!.end.offset, fix(corrector) { // corrector is inferred to be a JSONCorrector corrector.add(path, 'TODO'); }, }); // An unsafe change, add `defer` or `async` attributes on the script tag context.report({ message: 'Avoid parser blocking scripts by adding `defer` or `async` on this tag', startIndex: node.position.start, endIndex: node.position.end, suggest: [{ message: 'Add defer attribute', fix: corrector => { // corrector is inferred to be a StringCorrector corrector.insert(node.blockStartPosition.end, ' defer') }, }, { message: 'Add async attribute', fix: corrector => { // corrector is inferred to be a StringCorrector corrector.insert(node.blockStartPosition.end, ' async') }; }], })
Under the hood, corrector calls will be converted into a list of
Fix
objects.One can implement a
FixApplicator
(a async function that takes aSourceCode
andFix
objects) to apply fixes in different contexts.- In Node.js, we'll implement a
FixApplicator
that applies the fixes to the initial file and then save the changes to disk. - In the Language Server, we'll implement
FixApplicator
s that turn theFix
es intoTextEdit
objects.
New: the top level API now offers the
autofix
function, one that takes aFixApplicator
as argument.This
autofix
function applies all the safe changes (and ignores suggestions). -
- 9f8d47f: Fixup Translations type to allow strings
- a8cda19: Add TranslationKeyExists to allChecks array
- 9d419ca: Breaking: change dependency
get defaultLocale
togetDefaultLocale(): Promise<string>
-
72a9330: Breaking: Add
defaultLocale
dependency -
5329963: Breaking: create one context per file
The API for creating checks has changed:
- We no longer pass a
file
argument to every method file
is now accessible from theContext
object- We now create one context per file to avoid subtle state bugs
- We no longer pass a
-
72a9330: Add check TranslationKeyExists
-
5329963: Breaking: change signature of
getDefaultTranslations
to return aPromise<Translations>
- 4c099d5: Add check
MissingTemplate
- 4c099d5: Consider comments to disable checks (
# theme-check-disable/enable
)
-
f4a2f27: Simplify public API
Breaking changes:
Theme
isSourceCode<S>[]
instead of{ files: Map<string, SourceCode<S>> }
SourceCode
no longer has arelativePath
propertytoSourceCode
no longer takes arelativePath
as argumentConfig
has aroot
property
-
37fc98a: Add dependencies to public API
fileExists(absolutePath: string): Promise<boolean>
returns true when a file existsgetDefaultTranslations(): Promise<JSONObject>
returns the parsed JSON contents of the default translations file
These dependencies are now added to the
context
object and are usable by checks.Those exists as a lean way to get rid of the assumptions that all files are in the
Theme
object. We should be able to go a long way with these.
- d206674: Move toSourceCode to common for use in language-server-common
- 233f00f: Initial release