Skip to content

Commit a82deca

Browse files
committed
Added missing schema check for theme app extension
added context
1 parent a579d59 commit a82deca

File tree

6 files changed

+150
-0
lines changed

6 files changed

+150
-0
lines changed

.changeset/dirty-terms-refuse.md

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@shopify/theme-check-common': minor
3+
'@shopify/theme-check-node': minor
4+
---
5+
6+
Added MissingSchema theme check to identify missing schemas in theme app extensions.

packages/theme-check-common/src/checks/index.ts

+2
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ import { ValidSchema } from './valid-schema';
4040
import { ValidSchemaName } from './valid-schema-name';
4141
import { ValidStaticBlockType } from './valid-static-block-type';
4242
import { VariableName } from './variable-name';
43+
import { MissingSchema } from './missing-schema';
4344

4445
export const allChecks: (LiquidCheckDefinition | JSONCheckDefinition)[] = [
4546
AppBlockValidTags,
@@ -62,6 +63,7 @@ export const allChecks: (LiquidCheckDefinition | JSONCheckDefinition)[] = [
6263
MatchingTranslations,
6364
MissingAsset,
6465
MissingTemplate,
66+
MissingSchema,
6567
PaginationSize,
6668
ParserBlockingScript,
6769
RemoteAsset,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
import { describe, expect, it } from 'vitest';
2+
import { runLiquidCheck } from '../../test';
3+
import { MissingSchema } from './index';
4+
import { Config } from '../../types';
5+
6+
describe('MissingSchema', () => {
7+
it('should report an error when schema tag is missing on a theme app extension', async () => {
8+
const config: Config = {
9+
context: 'app',
10+
checks: [],
11+
rootUri: '',
12+
settings: {},
13+
};
14+
15+
const sourceCode = `
16+
<footer class="footer">
17+
{% for block in section.blocks %}
18+
{% case block.type %}
19+
{% when 'link' %}
20+
<div class="link" {{ block.shopify_attributes }}>
21+
{{ block.settings.linktext | link_to: block.settings.linkurl }}
22+
</div>
23+
24+
{% when 'custom-text' %}
25+
<div class="text" {{ block.shopify_attributes }}>
26+
{{ block.settings.custom-text-field }}
27+
</div>
28+
{% endcase %}
29+
{% endfor %}
30+
</footer>
31+
`;
32+
33+
const offenses = await runLiquidCheck(MissingSchema, sourceCode);
34+
expect(offenses).to.have.lengthOf(1);
35+
});
36+
37+
it('should not report when the schema is present on a theme app extension', async () => {
38+
const config: Config = {
39+
context: 'app',
40+
checks: [],
41+
rootUri: '',
42+
settings: {},
43+
};
44+
const sourceCode = `
45+
<footer class="footer">
46+
{% for block in section.blocks %}
47+
{% case block.type %}
48+
{% when 'link' %}
49+
<div class="link" {{ block.shopify_attributes }}>
50+
{{ block.settings.linktext | link_to: block.settings.linkurl }}
51+
</div>
52+
53+
{% when 'custom-text' %}
54+
<div class="text" {{ block.shopify_attributes }}>
55+
{{ block.settings.custom-text-field }}
56+
</div>
57+
{% endcase %}
58+
{% endfor %}
59+
</footer>
60+
61+
{% schema %}
62+
{
63+
"name": "Footer",
64+
"max_blocks": 8,
65+
"blocks": [
66+
{
67+
"type": "link",
68+
"name": "Link",
69+
"settings": [
70+
{
71+
"id": "linkurl",
72+
"type": "url",
73+
"label": "URL link"
74+
},
75+
{
76+
"id": "linktext",
77+
"type": "text",
78+
"label": "Link text"
79+
}
80+
]
81+
},
82+
{
83+
"type": "custom-text",
84+
"name": "Custom Text",
85+
"settings": [
86+
{
87+
"id": "custom-text-field",
88+
"type": "textarea",
89+
"label": "Text"
90+
}
91+
]
92+
}
93+
]
94+
}
95+
{% endschema %}`;
96+
97+
const offenses = await runLiquidCheck(MissingSchema, sourceCode);
98+
expect(offenses).to.have.lengthOf(0);
99+
});
100+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { ConfigTarget, LiquidCheckDefinition, Severity, SourceCodeType } from '../../types';
2+
3+
export const MissingSchema: LiquidCheckDefinition = {
4+
meta: {
5+
code: 'MissingSchema',
6+
name: 'Missing Schema',
7+
docs: {
8+
description: 'Check for missing schema definitions',
9+
recommended: true,
10+
},
11+
severity: Severity.ERROR,
12+
type: SourceCodeType.LiquidHtml,
13+
schema: {},
14+
targets: [ConfigTarget.ThemeAppExtension],
15+
},
16+
17+
create(context) {
18+
let foundSchema = false;
19+
20+
return {
21+
async LiquidRawTag(node) {
22+
if (node.name == 'schema') foundSchema = true;
23+
},
24+
25+
async onCodePathEnd() {
26+
if (!foundSchema) {
27+
context.report({
28+
message: `The schema does not exist`,
29+
startIndex: 0,
30+
endIndex: 0,
31+
});
32+
}
33+
},
34+
};
35+
},
36+
};

packages/theme-check-node/configs/all.yml

+3
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@ MatchingTranslations:
6464
MissingAsset:
6565
enabled: true
6666
severity: 0
67+
MissingSchema:
68+
enabled: false
69+
severity: 0
6770
MissingTemplate:
6871
enabled: true
6972
severity: 0

packages/theme-check-node/configs/theme-app-extension.yml

+3
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ AssetSizeAppBlockJavaScript:
1616
enabled: true
1717
severity: 0
1818
thresholdInBytes: 10000
19+
MissingSchema:
20+
enabled: true
21+
severity: 0
1922
RequiredLayoutThemeObject:
2023
enabled: false
2124
severity: 0

0 commit comments

Comments
 (0)