td-ai-tools 1.3.4 → 1.3.5
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.
- package/package.json +1 -1
- package/skills/shopify-lint/SKILL.md +1 -1
- package/skills/shopify-lint/scripts/__pycache__/shopify_lint.cpython-312.pyc +0 -0
- package/skills/shopify-lint/tests/__pycache__/test_shopify_lint.cpython-312.pyc +0 -0
- package/skills/shopify-lint/theme-check-theory/.theme-check.example.yml +4 -0
- package/skills/shopify-lint/theme-check-theory/README.md +43 -2
- package/skills/shopify-lint/theme-check-theory/configs/recommended.yml +4 -0
- package/skills/shopify-lint/theme-check-theory/src/checks/hardcoded-text.test.ts +6 -10
- package/skills/shopify-lint/theme-check-theory/src/checks/hardcoded-text.ts +0 -11
- package/skills/shopify-lint/theme-check-theory/src/checks/required-liquid-doc.test.ts +46 -0
- package/skills/shopify-lint/theme-check-theory/src/checks/required-liquid-doc.ts +111 -0
- package/skills/shopify-lint/theme-check-theory/src/index.test.ts +2 -0
- package/skills/shopify-lint/theme-check-theory/src/index.ts +3 -0
- package/skills/visual-regression/scripts/__pycache__/visual_regression.cpython-312.pyc +0 -0
- package/skills/shopify-lint/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +0 -1
- package/skills/shopify-pre-pr/scripts/__pycache__/test_vendor_change_audit.cpython-312.pyc +0 -0
- package/skills/shopify-pre-pr/scripts/__pycache__/vendor_change_audit.cpython-312.pyc +0 -0
package/package.json
CHANGED
|
@@ -40,7 +40,7 @@ python3 .agents/skills/shopify-lint/scripts/shopify_lint.py --path .
|
|
|
40
40
|
|
|
41
41
|
The script identifies files changed since the current branch's merge-base, adds staged, unstaged, and untracked files, then runs three linters over that set and merges their results into one report:
|
|
42
42
|
|
|
43
|
-
- **Theme Check** — `shopify theme check --output json`. The root `.theme-check.yml` directly requires the bundled `theme-check-theory` package from this skill directory. `DisallowedScriptOrStyleTag` reports inline executable `<script>` and all `<style>` tags in modified Liquid files while allowing external-source and JSON-data scripts. `HardcodedText` reports rendered hard-coded copy, except content inside Liquid `stylesheet`, `javascript`, and `schema` tags,
|
|
43
|
+
- **Theme Check** — `shopify theme check --output json`. The root `.theme-check.yml` directly requires the bundled `theme-check-theory` package from this skill directory. `DisallowedScriptOrStyleTag` reports inline executable `<script>` and all `<style>` tags in modified Liquid files while allowing external-source and JSON-data scripts. `HardcodedText` reports rendered hard-coded copy, except content inside Liquid `stylesheet`, `javascript`, and `schema` tags, except text beginning with `--`, which is a CSS custom property name rather than copy, and except string arguments passed to `{% render %}` and `{% include %}`, which are as often class names or size tokens as copy. The generated `.theme-check.yml` also pins the upstream `StaticStylesheetAndJavascriptTags` to `error`, so Liquid written inside a `{% stylesheet %}` or `{% javascript %}` block always fails the lint.
|
|
44
44
|
- **JavaScript** — ESLint's recommended rules plus the bundled `eslint-plugin-theory`, over modified `.js` and `.mjs` files *and* the JavaScript inside `{% javascript %}` blocks of modified `.liquid` files.
|
|
45
45
|
- **CSS** — `stylelint-config-standard` through the bundled `stylelint-config-theory`, over modified `.css` files *and* the CSS inside `{% stylesheet %}` blocks of modified `.liquid` files.
|
|
46
46
|
|
|
Binary file
|
|
Binary file
|
|
@@ -12,6 +12,10 @@ HardcodedText:
|
|
|
12
12
|
enabled: true
|
|
13
13
|
severity: warning
|
|
14
14
|
|
|
15
|
+
RequiredLiquidDoc:
|
|
16
|
+
enabled: true
|
|
17
|
+
severity: warning
|
|
18
|
+
|
|
15
19
|
# Upstream check, pinned here so the branch lint always fails on it: Shopify
|
|
16
20
|
# serves `{% stylesheet %}` and `{% javascript %}` bodies verbatim, so Liquid
|
|
17
21
|
# written inside one ships to the browser as literal text.
|
|
@@ -13,6 +13,7 @@ integrated into Shopify CLI. It is not compatible with the archived Ruby
|
|
|
13
13
|
| --- | --- | --- |
|
|
14
14
|
| `DisallowedScriptOrStyleTag` | warning | An inline executable `<script>` or any `<style>` tag in a Liquid file. |
|
|
15
15
|
| `HardcodedText` | warning | Rendered hard-coded storefront copy that should use a dynamic content source. |
|
|
16
|
+
| `RequiredLiquidDoc` | warning | A `td-` snippet or theme block without a complete Liquid doc contract. |
|
|
16
17
|
| `UnusedSectionSettings` | warning | A setting declared in `{% schema %}` that is never referenced in the file. |
|
|
17
18
|
| `UnguardedNullableSetting` | warning | A potentially blank setting output with `{{ }}` and no presence guard (`{% if %}`/`{% unless %}`) or `\| default`. |
|
|
18
19
|
| `UnguardedMetafield` | warning | A metafield output with no presence guard or `\| default`. |
|
|
@@ -33,12 +34,18 @@ Rendered storefront copy should come from a section setting, translation key,
|
|
|
33
34
|
metafield, or metaobject. The check reports text nodes, direct quoted output
|
|
34
35
|
with `{{ }}` or `{% echo %}`, quoted `default` filter fallbacks, hard-coded
|
|
35
36
|
`alt`, `title`, `placeholder`, and ARIA text attributes, and labels in the
|
|
36
|
-
`value` attribute of button-like inputs. Text inside inline SVG elements
|
|
37
|
-
string literals passed as named `render` or `include` arguments are also
|
|
37
|
+
`value` attribute of button-like inputs. Text inside inline SVG elements is also
|
|
38
38
|
checked. It ignores technical attributes such as classes and IDs, Liquid logic
|
|
39
39
|
strings, comments, punctuation-only fragments, and text made entirely of HTML
|
|
40
40
|
character references.
|
|
41
41
|
|
|
42
|
+
String literals passed as named `{% render %}` and `{% include %}` arguments are
|
|
43
|
+
ignored. A snippet argument is as often a class name, icon key, size token, or
|
|
44
|
+
heading level as it is storefront copy, and nothing at the call site separates
|
|
45
|
+
the two, so checking them produced mostly false positives. Copy that a snippet
|
|
46
|
+
renders is still reported inside the snippet itself, where it appears as a text
|
|
47
|
+
node or a quoted output.
|
|
48
|
+
|
|
42
49
|
Text beginning with `--` is ignored as a CSS custom property name: Liquid
|
|
43
50
|
routinely assembles a custom property declaration before handing it to a
|
|
44
51
|
`style` attribute or a `{% style %}` block, neither of which this check reads.
|
|
@@ -52,6 +59,36 @@ accepted. Short alphabetic tokens and copyright years remain reportable because
|
|
|
52
59
|
the check cannot reliably distinguish user-facing copy from currency codes,
|
|
53
60
|
units, or other intentional literals.
|
|
54
61
|
|
|
62
|
+
### RequiredLiquidDoc
|
|
63
|
+
|
|
64
|
+
Files whose name contains `td-` under `snippets/` or `blocks/` must contain a
|
|
65
|
+
`{% doc %}` tag with a prose description and a non-empty `@example`. Every
|
|
66
|
+
`@param` that is present must use LiquidDoc's `{type} name - description`
|
|
67
|
+
shape; optional names such as `[heading]` are supported. LiquidDoc types are
|
|
68
|
+
descriptive rather than a closed type system, so Shopify Liquid object names,
|
|
69
|
+
primitive names, and project-specific type expressions are all accepted.
|
|
70
|
+
|
|
71
|
+
```liquid
|
|
72
|
+
{% doc %}
|
|
73
|
+
Renders a product card.
|
|
74
|
+
|
|
75
|
+
@param {product} product - The product to display.
|
|
76
|
+
@param {string} [heading] - An optional card heading.
|
|
77
|
+
|
|
78
|
+
@example
|
|
79
|
+
{% render 'td-product-card', product: product, heading: 'Featured' %}
|
|
80
|
+
{% enddoc %}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
The check does not infer missing parameters from variable lookups inside the
|
|
84
|
+
file. Liquid exposes many global objects, and a snippet parameter is introduced
|
|
85
|
+
at its call site, so a single-file lookup cannot reliably distinguish the two.
|
|
86
|
+
To require complete parameter coverage, add a separate project-level analysis
|
|
87
|
+
that indexes named arguments at static `{% render %}` call sites and compares
|
|
88
|
+
their union with each target file's documented parameters. Dynamic snippet
|
|
89
|
+
names and values passed with `with`/`for` require an explicit project policy or
|
|
90
|
+
an allowlist.
|
|
91
|
+
|
|
55
92
|
### UnusedSectionSettings
|
|
56
93
|
|
|
57
94
|
This single-file check collects every `id` under `settings` and
|
|
@@ -185,6 +222,10 @@ HardcodedText:
|
|
|
185
222
|
enabled: true
|
|
186
223
|
severity: warning
|
|
187
224
|
|
|
225
|
+
RequiredLiquidDoc:
|
|
226
|
+
enabled: true
|
|
227
|
+
severity: warning
|
|
228
|
+
|
|
188
229
|
# Upstream check, pinned here so the branch lint always fails on it: Shopify
|
|
189
230
|
# serves `{% stylesheet %}` and `{% javascript %}` bodies verbatim, so Liquid
|
|
190
231
|
# written inside one ships to the browser as literal text.
|
|
@@ -98,22 +98,18 @@ describe('HardcodedText', () => {
|
|
|
98
98
|
]);
|
|
99
99
|
});
|
|
100
100
|
|
|
101
|
-
it('
|
|
101
|
+
it('ignores string literals passed as render and include arguments', async () => {
|
|
102
|
+
// A snippet argument is as often a class name, icon key, size token, or
|
|
103
|
+
// heading level as it is storefront copy, and the call site carries nothing
|
|
104
|
+
// that separates the two. The snippet body is still checked on its own.
|
|
102
105
|
const source = `
|
|
103
106
|
{% render 'button', label: 'Add to cart' %}
|
|
104
107
|
{% include 'icon', accessible_name: "Search icon" %}
|
|
105
|
-
{% render 'button',
|
|
108
|
+
{% render 'button', variant: 'primary', size: 'large' %}
|
|
106
109
|
{% render 'icon' %}
|
|
107
110
|
`;
|
|
108
111
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
expect(offenses).toHaveLength(2);
|
|
112
|
-
expect(
|
|
113
|
-
offenses.map(({ start, end }) =>
|
|
114
|
-
source.slice(start.index, end.index),
|
|
115
|
-
),
|
|
116
|
-
).toEqual(["'Add to cart'", '"Search icon"']);
|
|
112
|
+
expect(await runLiquidCheck(HardcodedText, source)).toEqual([]);
|
|
117
113
|
});
|
|
118
114
|
|
|
119
115
|
it('reports hard-coded default filter fallbacks', async () => {
|
|
@@ -308,17 +308,6 @@ export const HardcodedText: LiquidCheckDefinition = {
|
|
|
308
308
|
|
|
309
309
|
reportInlineSvgText(node);
|
|
310
310
|
},
|
|
311
|
-
|
|
312
|
-
async RenderMarkup(node) {
|
|
313
|
-
for (const argument of node.args) {
|
|
314
|
-
if (
|
|
315
|
-
argument.type === NodeTypes.NamedArgument &&
|
|
316
|
-
argument.value.type === NodeTypes.String
|
|
317
|
-
) {
|
|
318
|
-
reportString(argument.value);
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
},
|
|
322
311
|
};
|
|
323
312
|
},
|
|
324
313
|
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
|
|
3
|
+
import { liquidDocProblems, requiresLiquidDoc } from './required-liquid-doc';
|
|
4
|
+
|
|
5
|
+
describe('RequiredLiquidDoc', () => {
|
|
6
|
+
it('targets td- Liquid snippets and blocks only', () => {
|
|
7
|
+
expect(requiresLiquidDoc('file:///theme/snippets/td-card.liquid')).toBe(true);
|
|
8
|
+
expect(requiresLiquidDoc('/theme/blocks/product-td-card.liquid')).toBe(true);
|
|
9
|
+
expect(requiresLiquidDoc('/theme/sections/td-card.liquid')).toBe(false);
|
|
10
|
+
expect(requiresLiquidDoc('/theme/snippets/card.liquid')).toBe(false);
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it('accepts a description, typed parameters, and an example', () => {
|
|
14
|
+
const body = `
|
|
15
|
+
Renders a card for a product.
|
|
16
|
+
@param {product} product - The product displayed by the card.
|
|
17
|
+
@param {string} [heading] - An optional heading.
|
|
18
|
+
@example
|
|
19
|
+
{% render 'td-card', product: product, heading: 'Featured' %}
|
|
20
|
+
`;
|
|
21
|
+
expect(liquidDocProblems(body)).toEqual([]);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('requires both a description and non-empty example', () => {
|
|
25
|
+
expect(liquidDocProblems('@example\n').map(({ message }) => message)).toEqual([
|
|
26
|
+
'Liquid doc must include a description before its annotations',
|
|
27
|
+
'Liquid doc must include an @example with example markup',
|
|
28
|
+
]);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('requires types and descriptions on documented parameters', () => {
|
|
32
|
+
const body = `
|
|
33
|
+
Renders a card.
|
|
34
|
+
@param product - The product.
|
|
35
|
+
@param {string} heading
|
|
36
|
+
@example
|
|
37
|
+
{% render 'td-card', product: product %}
|
|
38
|
+
`;
|
|
39
|
+
expect(liquidDocProblems(body).map(({ message }) => message)).toEqual([
|
|
40
|
+
'Liquid doc @param must include a type in braces',
|
|
41
|
+
'Liquid doc @param must include a description after " - "',
|
|
42
|
+
'Liquid doc @param must include a type in braces',
|
|
43
|
+
'Liquid doc @param must include a description after " - "',
|
|
44
|
+
]);
|
|
45
|
+
});
|
|
46
|
+
});
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import type { LiquidRawTag } from '@shopify/liquid-html-parser';
|
|
2
|
+
import {
|
|
3
|
+
LiquidCheckDefinition,
|
|
4
|
+
Severity,
|
|
5
|
+
SourceCodeType,
|
|
6
|
+
} from '@shopify/theme-check-common';
|
|
7
|
+
|
|
8
|
+
type DocumentationProblem = { message: string; offset: number; length: number };
|
|
9
|
+
|
|
10
|
+
const PARAM_LINE = /^[ \t]*@param[ \t]+(.*)$/gm;
|
|
11
|
+
const COMPLETE_PARAM = /^\{([^}\n]+)\}\s+(\[[^\]\n]+\]|[^\s-]+)\s+-\s+(.+)$/;
|
|
12
|
+
|
|
13
|
+
/** Returns true for td-named snippets and theme blocks. */
|
|
14
|
+
export function requiresLiquidDoc(uri: string): boolean {
|
|
15
|
+
const path = decodeURIComponent(uri).replace(/\\/g, '/').split(/[?#]/, 1)[0];
|
|
16
|
+
const match = path.match(/(?:^|\/)(snippets|blocks)\/([^/]+)\.liquid$/i);
|
|
17
|
+
return Boolean(match?.[2].toLowerCase().includes('td-'));
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** Validates the documented contract without mistaking Shopify globals for parameters. */
|
|
21
|
+
export function liquidDocProblems(body: string): DocumentationProblem[] {
|
|
22
|
+
const problems: DocumentationProblem[] = [];
|
|
23
|
+
const firstAnnotation = body.search(/^[ \t]*@\w+/m);
|
|
24
|
+
const description = body.slice(0, firstAnnotation < 0 ? body.length : firstAnnotation).trim();
|
|
25
|
+
|
|
26
|
+
if (!description) {
|
|
27
|
+
problems.push({
|
|
28
|
+
message: 'Liquid doc must include a description before its annotations',
|
|
29
|
+
offset: 0,
|
|
30
|
+
length: Math.max(body.length, 1),
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const example = body.match(
|
|
35
|
+
/^[ \t]*@example[^\n]*\n([\s\S]*?)(?=^[ \t]*@\w+|(?![\s\S]))/m,
|
|
36
|
+
);
|
|
37
|
+
if (!example || !example[1].trim()) {
|
|
38
|
+
problems.push({
|
|
39
|
+
message: 'Liquid doc must include an @example with example markup',
|
|
40
|
+
offset: 0,
|
|
41
|
+
length: Math.max(body.length, 1),
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
for (const match of body.matchAll(PARAM_LINE)) {
|
|
46
|
+
const complete = match[1].trim().match(COMPLETE_PARAM);
|
|
47
|
+
const offset = match.index ?? 0;
|
|
48
|
+
if (!complete?.[1].trim()) {
|
|
49
|
+
problems.push({
|
|
50
|
+
message: 'Liquid doc @param must include a type in braces',
|
|
51
|
+
offset,
|
|
52
|
+
length: match[0].length,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
if (!complete?.[3].trim()) {
|
|
56
|
+
problems.push({
|
|
57
|
+
message: 'Liquid doc @param must include a description after " - "',
|
|
58
|
+
offset,
|
|
59
|
+
length: match[0].length,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return problems;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export const RequiredLiquidDoc: LiquidCheckDefinition = {
|
|
68
|
+
meta: {
|
|
69
|
+
code: 'RequiredLiquidDoc',
|
|
70
|
+
name: 'Require documentation for td- snippets and theme blocks',
|
|
71
|
+
docs: {
|
|
72
|
+
description:
|
|
73
|
+
'Requires td- snippets and blocks to have a Liquid doc description and example, and validates documented parameters.',
|
|
74
|
+
recommended: true,
|
|
75
|
+
},
|
|
76
|
+
type: SourceCodeType.LiquidHtml,
|
|
77
|
+
severity: Severity.WARNING,
|
|
78
|
+
schema: {},
|
|
79
|
+
},
|
|
80
|
+
create(context) {
|
|
81
|
+
const uri = (context as unknown as { file?: { uri?: string } }).file?.uri ?? '';
|
|
82
|
+
if (!requiresLiquidDoc(uri)) return {};
|
|
83
|
+
|
|
84
|
+
const docs: LiquidRawTag[] = [];
|
|
85
|
+
return {
|
|
86
|
+
async LiquidRawTag(node) {
|
|
87
|
+
if (node.name === 'doc') docs.push(node);
|
|
88
|
+
},
|
|
89
|
+
async onCodePathEnd() {
|
|
90
|
+
if (docs.length === 0) {
|
|
91
|
+
context.report({
|
|
92
|
+
message: 'td- snippets and blocks must include a {% doc %} tag',
|
|
93
|
+
startIndex: 0,
|
|
94
|
+
endIndex: 1,
|
|
95
|
+
});
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const doc = docs[0];
|
|
100
|
+
for (const problem of liquidDocProblems(doc.body.value)) {
|
|
101
|
+
const startIndex = doc.body.position.start + problem.offset;
|
|
102
|
+
context.report({
|
|
103
|
+
message: problem.message,
|
|
104
|
+
startIndex,
|
|
105
|
+
endIndex: startIndex + problem.length,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
},
|
|
111
|
+
};
|
|
@@ -8,6 +8,7 @@ describe('theme-check-theory module', () => {
|
|
|
8
8
|
expect(checks.map(({ meta }) => meta.code)).toEqual([
|
|
9
9
|
'DisallowedScriptOrStyleTag',
|
|
10
10
|
'HardcodedText',
|
|
11
|
+
'RequiredLiquidDoc',
|
|
11
12
|
'UnusedSectionSettings',
|
|
12
13
|
'UnguardedNullableSetting',
|
|
13
14
|
'UnguardedMetafield',
|
|
@@ -24,6 +25,7 @@ describe('theme-check-theory module', () => {
|
|
|
24
25
|
).toEqual({
|
|
25
26
|
DisallowedScriptOrStyleTag: true,
|
|
26
27
|
HardcodedText: true,
|
|
28
|
+
RequiredLiquidDoc: true,
|
|
27
29
|
UnusedSectionSettings: false,
|
|
28
30
|
UnguardedNullableSetting: true,
|
|
29
31
|
UnguardedMetafield: true,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { DisallowedScriptOrStyleTag } from './checks/disallowed-script-or-style-tag';
|
|
2
2
|
import { HardcodedText } from './checks/hardcoded-text';
|
|
3
|
+
import { RequiredLiquidDoc } from './checks/required-liquid-doc';
|
|
3
4
|
import { UnusedSectionSettings } from './checks/unused-section-settings';
|
|
4
5
|
import { UnguardedMetafield } from './checks/unguarded-metafield';
|
|
5
6
|
import { UnguardedMetaobject } from './checks/unguarded-metaobject';
|
|
@@ -7,6 +8,7 @@ import { UnguardedNullableSetting } from './checks/unguarded-nullable-setting';
|
|
|
7
8
|
|
|
8
9
|
export { DisallowedScriptOrStyleTag } from './checks/disallowed-script-or-style-tag';
|
|
9
10
|
export { HardcodedText } from './checks/hardcoded-text';
|
|
11
|
+
export { RequiredLiquidDoc } from './checks/required-liquid-doc';
|
|
10
12
|
export { UnusedSectionSettings } from './checks/unused-section-settings';
|
|
11
13
|
export { UnguardedMetafield } from './checks/unguarded-metafield';
|
|
12
14
|
export { UnguardedMetaobject } from './checks/unguarded-metaobject';
|
|
@@ -18,6 +20,7 @@ export {
|
|
|
18
20
|
export const checks = [
|
|
19
21
|
DisallowedScriptOrStyleTag,
|
|
20
22
|
HardcodedText,
|
|
23
|
+
RequiredLiquidDoc,
|
|
21
24
|
UnusedSectionSettings,
|
|
22
25
|
UnguardedNullableSetting,
|
|
23
26
|
UnguardedMetafield,
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":"4.1.10","results":[[":eslint-plugin-theory/src/rules/guarded-custom-element-define.test.ts",{"duration":0,"failed":true}],[":stylelint-config-theory/src/liquid/mask.test.ts",{"duration":21.486761,"failed":false}],[":theme-check-theory/src/checks/hardcoded-text.test.ts",{"duration":79.642067,"failed":false}],[":stylelint-config-theory/src/integration.test.ts",{"duration":322.234405,"failed":false}],[":theme-check-theory/src/checks/unguarded-nullable-setting.test.ts",{"duration":126.54217099999994,"failed":false}],[":eslint-plugin-theory/src/rules/disconnected-callback-cleanup.test.ts",{"duration":0,"failed":true}],[":eslint-plugin-theory/src/integration.test.ts",{"duration":207.055841,"failed":false}],[":eslint-plugin-theory/src/liquid/mask.test.ts",{"duration":31.769655,"failed":false}],[":stylelint-config-theory/src/config.test.ts",{"duration":13.856021999999996,"failed":false}],[":theme-check-theory/src/checks/unused-section-settings.test.ts",{"duration":63.80623400000002,"failed":false}],[":theme-check-theory/src/checks/unguarded-metaobject.test.ts",{"duration":34.325909000000024,"failed":false}],[":eslint-plugin-theory/src/index.test.ts",{"duration":6.773288999999977,"failed":false}],[":theme-check-theory/src/checks/disallowed-script-or-style-tag.test.ts",{"duration":32.848730000000046,"failed":false}],[":theme-check-theory/src/checks/unguarded-metafield.test.ts",{"duration":37.897699999999986,"failed":false}],[":eslint-plugin-theory/src/rules/no-class-selectors.test.ts",{"duration":0,"failed":true}],[":eslint-plugin-theory/src/rules/no-unapproved-imports.test.ts",{"duration":0,"failed":true}],[":eslint-plugin-theory/src/rules/require-jsdoc.test.ts",{"duration":87.66796799999997,"failed":false}],[":eslint-plugin-theory/src/rules/centralize-selectors.test.ts",{"duration":0,"failed":true}],[":stylelint-config-theory/src/build.test.ts",{"duration":903.9329710000001,"failed":false}],[":theme-check-theory/src/index.test.ts",{"duration":2.380390000000034,"failed":false}],[":eslint-plugin-theory/src/processors/liquid.test.ts",{"duration":6.720345000000009,"failed":false}],[":eslint-plugin-theory/src/build.test.ts",{"duration":965.007413,"failed":false}]]}
|
|
Binary file
|