@platformos/platformos-check-common 0.0.6 → 0.0.8
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/CHANGELOG.md +16 -0
- package/dist/AugmentedPlatformOSDocset.d.ts +11 -0
- package/dist/AugmentedPlatformOSDocset.js +81 -0
- package/dist/AugmentedPlatformOSDocset.js.map +1 -0
- package/dist/JSONValidator.js +1 -1
- package/dist/JSONValidator.js.map +1 -1
- package/dist/checks/deprecated-filter/index.js +4 -41
- package/dist/checks/deprecated-filter/index.js.map +1 -1
- package/dist/checks/deprecated-tag/index.js +21 -22
- package/dist/checks/deprecated-tag/index.js.map +1 -1
- package/dist/checks/duplicate-function-arguments/index.js +1 -1
- package/dist/checks/duplicate-function-arguments/index.js.map +1 -1
- package/dist/checks/duplicate-render-partial-arguments/index.js +1 -1
- package/dist/checks/duplicate-render-partial-arguments/index.js.map +1 -1
- package/dist/checks/graphql/index.js +1 -1
- package/dist/checks/graphql/index.js.map +1 -1
- package/dist/checks/img-width-and-height/index.js +1 -1
- package/dist/checks/img-width-and-height/index.js.map +1 -1
- package/dist/checks/index.d.ts +3 -3
- package/dist/checks/index.js +4 -79
- package/dist/checks/index.js.map +1 -1
- package/dist/checks/json-syntax-error/index.js +1 -1
- package/dist/checks/json-syntax-error/index.js.map +1 -1
- package/dist/checks/liquid-html-syntax-error/index.js +2 -2
- package/dist/checks/liquid-html-syntax-error/index.js.map +1 -1
- package/dist/checks/matching-translations/index.d.ts +2 -2
- package/dist/checks/matching-translations/index.js +20 -31
- package/dist/checks/matching-translations/index.js.map +1 -1
- package/dist/checks/metadata-params/index.js +6 -3
- package/dist/checks/metadata-params/index.js.map +1 -1
- package/dist/checks/missing-asset/index.js +1 -1
- package/dist/checks/missing-asset/index.js.map +1 -1
- package/dist/checks/missing-partial/index.d.ts +6 -0
- package/dist/checks/missing-partial/index.js +70 -0
- package/dist/checks/missing-partial/index.js.map +1 -0
- package/dist/checks/orphaned-partial/index.js +4 -4
- package/dist/checks/orphaned-partial/index.js.map +1 -1
- package/dist/checks/parser-blocking-script/index.js +10 -36
- package/dist/checks/parser-blocking-script/index.js.map +1 -1
- package/dist/checks/parser-blocking-script/suggestions.d.ts +1 -2
- package/dist/checks/parser-blocking-script/suggestions.js +1 -11
- package/dist/checks/parser-blocking-script/suggestions.js.map +1 -1
- package/dist/checks/reserved-doc-param-names/index.js +6 -5
- package/dist/checks/reserved-doc-param-names/index.js.map +1 -1
- package/dist/checks/translation-key-exists/index.js +1 -1
- package/dist/checks/translation-key-exists/index.js.map +1 -1
- package/dist/checks/unclosed-html-element/index.js +5 -1
- package/dist/checks/unclosed-html-element/index.js.map +1 -1
- package/dist/checks/undefined-object/index.js +7 -30
- package/dist/checks/undefined-object/index.js.map +1 -1
- package/dist/checks/unique-doc-param-names/index.js +1 -1
- package/dist/checks/unique-doc-param-names/index.js.map +1 -1
- package/dist/checks/unknown-filter/index.js +3 -3
- package/dist/checks/unknown-filter/index.js.map +1 -1
- package/dist/checks/unknown-property/index.js +1 -1
- package/dist/checks/unknown-property/index.js.map +1 -1
- package/dist/checks/unrecognized-render-partial-arguments/index.js +2 -2
- package/dist/checks/unrecognized-render-partial-arguments/index.js.map +1 -1
- package/dist/checks/unused-assign/index.js +1 -1
- package/dist/checks/unused-assign/index.js.map +1 -1
- package/dist/checks/unused-doc-param/index.js +1 -1
- package/dist/checks/unused-doc-param/index.js.map +1 -1
- package/dist/checks/utils.js +1 -1
- package/dist/checks/utils.js.map +1 -1
- package/dist/checks/valid-content-for-arguments/index.js +1 -1
- package/dist/checks/valid-content-for-arguments/index.js.map +1 -1
- package/dist/checks/valid-doc-param-types/index.js +4 -4
- package/dist/checks/valid-doc-param-types/index.js.map +1 -1
- package/dist/checks/valid-html-translation/index.d.ts +2 -2
- package/dist/checks/valid-html-translation/index.js +4 -4
- package/dist/checks/valid-html-translation/index.js.map +1 -1
- package/dist/checks/valid-json/index.js +1 -1
- package/dist/checks/valid-json/index.js.map +1 -1
- package/dist/checks/valid-render-partial-argument-types/index.js +2 -2
- package/dist/checks/valid-render-partial-argument-types/index.js.map +1 -1
- package/dist/checks/variable-name/index.js +1 -1
- package/dist/checks/variable-name/index.js.map +1 -1
- package/dist/context-utils.d.ts +2 -7
- package/dist/context-utils.js +39 -109
- package/dist/context-utils.js.map +1 -1
- package/dist/disabled-checks/index.js +4 -2
- package/dist/disabled-checks/index.js.map +1 -1
- package/dist/find-root.d.ts +7 -10
- package/dist/find-root.js +10 -17
- package/dist/find-root.js.map +1 -1
- package/dist/fixes/autofix.d.ts +4 -4
- package/dist/fixes/autofix.js +2 -2
- package/dist/fixes/autofix.js.map +1 -1
- package/dist/fixes/correctors/index.js +4 -0
- package/dist/fixes/correctors/index.js.map +1 -1
- package/dist/index.d.ts +4 -5
- package/dist/index.js +34 -17
- package/dist/index.js.map +1 -1
- package/dist/jsonc/parse.d.ts +1 -1
- package/dist/jsonc/parse.js +1 -1
- package/dist/liquid-doc/arguments.d.ts +7 -8
- package/dist/liquid-doc/arguments.js +20 -28
- package/dist/liquid-doc/arguments.js.map +1 -1
- package/dist/liquid-doc/liquidDoc.d.ts +1 -1
- package/dist/liquid-doc/liquidDoc.js.map +1 -1
- package/dist/liquid-doc/utils.d.ts +1 -1
- package/dist/liquid-doc/utils.js +4 -3
- package/dist/liquid-doc/utils.js.map +1 -1
- package/dist/path.d.ts +1 -0
- package/dist/path.js +5 -1
- package/dist/path.js.map +1 -1
- package/dist/test/MockApp.d.ts +16 -0
- package/dist/test/MockApp.js +16 -0
- package/dist/test/MockApp.js.map +1 -0
- package/dist/test/MockFileSystem.d.ts +3 -3
- package/dist/test/MockFileSystem.js +6 -6
- package/dist/test/MockFileSystem.js.map +1 -1
- package/dist/test/index.d.ts +1 -1
- package/dist/test/index.js +1 -1
- package/dist/test/index.js.map +1 -1
- package/dist/test/test-helper.d.ts +10 -9
- package/dist/test/test-helper.js +15 -106
- package/dist/test/test-helper.js.map +1 -1
- package/dist/to-source-code.d.ts +4 -3
- package/dist/to-source-code.js +20 -0
- package/dist/to-source-code.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/platformos-liquid-docs.d.ts +128 -0
- package/dist/types/platformos-liquid-docs.js +3 -0
- package/dist/types/platformos-liquid-docs.js.map +1 -0
- package/dist/types/schemas/index.d.ts +0 -2
- package/dist/types/schemas/index.js.map +1 -1
- package/dist/types.d.ts +18 -67
- package/dist/types.js +3 -5
- package/dist/types.js.map +1 -1
- package/dist/utils/file-utils.js +1 -2
- package/dist/utils/file-utils.js.map +1 -1
- package/dist/utils/index.d.ts +0 -1
- package/dist/utils/index.js +0 -1
- package/dist/utils/index.js.map +1 -1
- package/dist/yaml/parse.d.ts +5 -0
- package/dist/yaml/parse.js +94 -0
- package/dist/yaml/parse.js.map +1 -0
- package/package.json +9 -9
- package/src/{AugmentedThemeDocset.spec.ts → AugmentedPlatformOSDocset.spec.ts} +47 -34
- package/src/AugmentedPlatformOSDocset.ts +89 -0
- package/src/JSONValidator.ts +1 -1
- package/src/checks/deprecated-filter/index.spec.ts +76 -248
- package/src/checks/deprecated-filter/index.ts +5 -53
- package/src/checks/deprecated-tag/index.spec.ts +85 -34
- package/src/checks/deprecated-tag/index.ts +27 -22
- package/src/checks/duplicate-function-arguments/index.ts +1 -1
- package/src/checks/duplicate-render-partial-arguments/index.ts +1 -1
- package/src/checks/graphql/index.ts +1 -1
- package/src/checks/img-width-and-height/index.ts +1 -1
- package/src/checks/index.ts +11 -80
- package/src/checks/invalid-hash-assign-target/index.spec.ts +14 -14
- package/src/checks/json-syntax-error/index.ts +1 -1
- package/src/checks/liquid-html-syntax-error/checks/InvalidBooleanExpression.spec.ts +0 -11
- package/src/checks/liquid-html-syntax-error/checks/InvalidLoopArguments.spec.ts +1 -2
- package/src/checks/liquid-html-syntax-error/index.spec.ts +1 -6
- package/src/checks/liquid-html-syntax-error/index.ts +2 -2
- package/src/checks/matching-translations/index.spec.ts +89 -346
- package/src/checks/matching-translations/index.ts +24 -35
- package/src/checks/metadata-params/index.ts +5 -7
- package/src/checks/missing-asset/index.ts +1 -1
- package/src/checks/{missing-template → missing-partial}/index.spec.ts +6 -6
- package/src/checks/{missing-template → missing-partial}/index.ts +6 -20
- package/src/checks/orphaned-partial/index.ts +3 -3
- package/src/checks/parser-blocking-script/index.spec.ts +0 -118
- package/src/checks/parser-blocking-script/index.ts +3 -33
- package/src/checks/parser-blocking-script/suggestions.ts +1 -28
- package/src/checks/translation-key-exists/index.ts +1 -1
- package/src/checks/unclosed-html-element/index.ts +5 -1
- package/src/checks/undefined-object/index.spec.ts +3 -109
- package/src/checks/undefined-object/index.ts +8 -33
- package/src/checks/unique-doc-param-names/index.ts +1 -1
- package/src/checks/unknown-filter/index.spec.ts +2 -2
- package/src/checks/unknown-filter/index.ts +3 -3
- package/src/checks/unknown-property/index.ts +1 -1
- package/src/checks/unrecognized-render-partial-arguments/index.spec.ts +5 -5
- package/src/checks/unrecognized-render-partial-arguments/index.ts +2 -5
- package/src/checks/unused-assign/index.spec.ts +0 -30
- package/src/checks/unused-assign/index.ts +1 -1
- package/src/checks/unused-doc-param/index.ts +1 -1
- package/src/checks/utils.ts +1 -1
- package/src/checks/valid-doc-param-types/index.ts +4 -4
- package/src/checks/valid-html-translation/index.spec.ts +42 -32
- package/src/checks/valid-html-translation/index.ts +7 -7
- package/src/checks/valid-json/index.ts +1 -1
- package/src/checks/valid-render-partial-argument-types/index.ts +2 -5
- package/src/checks/variable-name/index.ts +1 -1
- package/src/context-utils.spec.ts +49 -77
- package/src/context-utils.ts +39 -128
- package/src/disabled-checks/index.spec.ts +35 -0
- package/src/disabled-checks/index.ts +4 -2
- package/src/find-root.ts +12 -22
- package/src/fixes/autofix.spec.ts +2 -2
- package/src/fixes/autofix.ts +4 -4
- package/src/fixes/correctors/index.ts +4 -0
- package/src/ignore.spec.ts +0 -1
- package/src/index.ts +33 -21
- package/src/jsonc/parse.ts +1 -1
- package/src/liquid-doc/arguments.spec.ts +19 -45
- package/src/liquid-doc/arguments.ts +26 -39
- package/src/liquid-doc/liquidDoc.ts +1 -2
- package/src/liquid-doc/utils.ts +4 -3
- package/src/path.ts +1 -0
- package/src/test/{MockTheme.ts → MockApp.ts} +1 -1
- package/src/test/MockFileSystem.ts +9 -6
- package/src/test/index.ts +1 -1
- package/src/test/test-helper.ts +29 -127
- package/src/to-source-code.ts +20 -1
- package/src/types/{theme-liquid-docs.ts → platformos-liquid-docs.ts} +8 -13
- package/src/types/schemas/index.ts +0 -2
- package/src/types.ts +21 -92
- package/src/utils/file-utils.ts +0 -1
- package/src/utils/index.ts +0 -1
- package/src/yaml/parse.ts +111 -0
- package/src/AugmentedThemeDocset.ts +0 -137
- package/src/checks/app-block-missing-schema/index.spec.ts +0 -121
- package/src/checks/app-block-missing-schema/index.ts +0 -46
- package/src/checks/app-block-valid-tags/index.spec.ts +0 -96
- package/src/checks/app-block-valid-tags/index.ts +0 -54
- package/src/checks/asset-preload/index.spec.ts +0 -78
- package/src/checks/asset-preload/index.ts +0 -65
- package/src/checks/asset-size-app-block-css/index.spec.ts +0 -88
- package/src/checks/asset-size-app-block-css/index.ts +0 -78
- package/src/checks/asset-size-app-block-javascript/index.spec.ts +0 -66
- package/src/checks/asset-size-app-block-javascript/index.ts +0 -78
- package/src/checks/asset-size-css/index.spec.ts +0 -166
- package/src/checks/asset-size-css/index.ts +0 -160
- package/src/checks/asset-size-javascript/index.spec.ts +0 -184
- package/src/checks/asset-size-javascript/index.ts +0 -144
- package/src/checks/block-id-usage/index.spec.ts +0 -76
- package/src/checks/block-id-usage/index.ts +0 -72
- package/src/checks/cdn-preconnect/index.spec.ts +0 -40
- package/src/checks/cdn-preconnect/index.ts +0 -43
- package/src/checks/content-for-header-modification/index.spec.ts +0 -65
- package/src/checks/content-for-header-modification/index.ts +0 -72
- package/src/checks/deprecate-bgsizes/index.spec.ts +0 -41
- package/src/checks/deprecate-bgsizes/index.ts +0 -49
- package/src/checks/deprecate-lazysizes/index.spec.ts +0 -26
- package/src/checks/deprecate-lazysizes/index.ts +0 -58
- package/src/checks/deprecated-filter/fixes.ts +0 -264
- package/src/checks/deprecated-fonts-on-sections-and-blocks/deprecated-fonts-data.ts +0 -1343
- package/src/checks/deprecated-fonts-on-sections-and-blocks/index.spec.ts +0 -613
- package/src/checks/deprecated-fonts-on-sections-and-blocks/index.ts +0 -284
- package/src/checks/deprecated-fonts-on-settings-schema/index.spec.ts +0 -102
- package/src/checks/deprecated-fonts-on-settings-schema/index.ts +0 -66
- package/src/checks/duplicate-content-for-arguments/index.spec.ts +0 -98
- package/src/checks/duplicate-content-for-arguments/index.ts +0 -43
- package/src/checks/empty-block-content/index.spec.ts +0 -117
- package/src/checks/empty-block-content/index.ts +0 -60
- package/src/checks/hardcoded-routes/index.spec.ts +0 -58
- package/src/checks/hardcoded-routes/index.ts +0 -100
- package/src/checks/json-missing-block/index.spec.ts +0 -435
- package/src/checks/json-missing-block/index.ts +0 -56
- package/src/checks/json-missing-block/missing-block-utils.ts +0 -147
- package/src/checks/liquid-free-settings/index.spec.ts +0 -180
- package/src/checks/liquid-free-settings/index.ts +0 -79
- package/src/checks/missing-content-for-arguments/index.spec.ts +0 -144
- package/src/checks/missing-content-for-arguments/index.ts +0 -46
- package/src/checks/pagination-size/index.spec.ts +0 -158
- package/src/checks/pagination-size/index.ts +0 -104
- package/src/checks/remote-asset/index.spec.ts +0 -280
- package/src/checks/remote-asset/index.ts +0 -238
- package/src/checks/reserved-doc-param-names/index.spec.ts +0 -62
- package/src/checks/reserved-doc-param-names/index.ts +0 -57
- package/src/checks/schema-presets-block-order/index.spec.ts +0 -344
- package/src/checks/schema-presets-block-order/index.ts +0 -154
- package/src/checks/schema-presets-static-blocks/index.spec.ts +0 -145
- package/src/checks/schema-presets-static-blocks/index.ts +0 -126
- package/src/checks/static-stylesheet-and-javascript-tags/index.spec.ts +0 -257
- package/src/checks/static-stylesheet-and-javascript-tags/index.ts +0 -48
- package/src/checks/unique-settings-id/index.spec.ts +0 -24
- package/src/checks/unique-settings-id/index.ts +0 -84
- package/src/checks/unique-settings-id/test-data.ts +0 -1191
- package/src/checks/unique-static-block-id/index.spec.ts +0 -55
- package/src/checks/unique-static-block-id/index.ts +0 -60
- package/src/checks/unrecognized-content-for-arguments/index.spec.ts +0 -145
- package/src/checks/unrecognized-content-for-arguments/index.ts +0 -55
- package/src/checks/valid-block-target/index.spec.ts +0 -1396
- package/src/checks/valid-block-target/index.ts +0 -142
- package/src/checks/valid-content-for-argument-types/index.spec.ts +0 -382
- package/src/checks/valid-content-for-argument-types/index.ts +0 -42
- package/src/checks/valid-content-for-arguments/index.spec.ts +0 -107
- package/src/checks/valid-content-for-arguments/index.ts +0 -98
- package/src/checks/valid-local-blocks/index.spec.ts +0 -286
- package/src/checks/valid-local-blocks/index.ts +0 -100
- package/src/checks/valid-local-blocks/valid-block-utils.ts +0 -97
- package/src/checks/valid-schema/index.spec.ts +0 -174
- package/src/checks/valid-schema/index.ts +0 -41
- package/src/checks/valid-schema-name/index.spec.ts +0 -112
- package/src/checks/valid-schema-name/index.ts +0 -75
- package/src/checks/valid-settings-key/index.spec.ts +0 -321
- package/src/checks/valid-settings-key/index.ts +0 -144
- package/src/checks/valid-static-block-type/index.spec.ts +0 -38
- package/src/checks/valid-static-block-type/index.ts +0 -58
- package/src/checks/valid-visible-if/index.spec.ts +0 -619
- package/src/checks/valid-visible-if/index.ts +0 -184
- package/src/checks/valid-visible-if/visible-if-utils.ts +0 -158
- package/src/tags/content-for.ts +0 -25
- package/src/to-schema.ts +0 -231
- package/src/types/schemas/section.ts +0 -86
- package/src/types/schemas/theme-block.ts +0 -34
- package/src/types/theme-schemas.ts +0 -80
- package/src/utils/block.ts +0 -300
- package/src/utils/markup.ts +0 -10
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { isMap, isScalar, isSeq, isPair, parseDocument } from 'yaml';
|
|
2
|
+
import type { Pair, Scalar, YAMLMap, YAMLSeq } from 'yaml';
|
|
3
|
+
import type {
|
|
4
|
+
ArrayNode,
|
|
5
|
+
IdentifierNode,
|
|
6
|
+
JSONNode,
|
|
7
|
+
LiteralNode,
|
|
8
|
+
Location,
|
|
9
|
+
ObjectNode,
|
|
10
|
+
PropertyNode,
|
|
11
|
+
ValueNode,
|
|
12
|
+
} from '../jsonc/types';
|
|
13
|
+
|
|
14
|
+
export class YAMLConvertError extends Error {
|
|
15
|
+
constructor(message: string) {
|
|
16
|
+
super(message);
|
|
17
|
+
this.name = 'YAMLConvertError';
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function loc(start: number, end: number): Location {
|
|
22
|
+
return { start: { offset: start }, end: { offset: end } };
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function getRange(node: any): [number, number] {
|
|
26
|
+
if (node && node.range && Array.isArray(node.range)) {
|
|
27
|
+
const start = node.range[0] ?? 0;
|
|
28
|
+
const end = node.range[1] ?? 0;
|
|
29
|
+
return [start, end];
|
|
30
|
+
}
|
|
31
|
+
return [0, 0];
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function toYAMLNode(source: string): JSONNode {
|
|
35
|
+
const doc = parseDocument(source);
|
|
36
|
+
|
|
37
|
+
if (doc.errors.length > 0) {
|
|
38
|
+
throw new YAMLConvertError(doc.errors[0].message);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (doc.contents === null || doc.contents === undefined) {
|
|
42
|
+
return { type: 'Object', children: [], loc: loc(0, 0) } as ObjectNode;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return convertNode(doc.contents as any, source) as JSONNode;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function convertNode(node: any, source: string): JSONNode {
|
|
49
|
+
if (isMap(node)) return convertMap(node, source);
|
|
50
|
+
if (isSeq(node)) return convertSeq(node, source);
|
|
51
|
+
if (isScalar(node)) return convertScalar(node);
|
|
52
|
+
return { type: 'Literal', value: null, raw: 'null', loc: loc(0, 0) } as LiteralNode;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function convertMap(node: YAMLMap, source: string): ObjectNode {
|
|
56
|
+
const [start, end] = getRange(node);
|
|
57
|
+
return {
|
|
58
|
+
type: 'Object',
|
|
59
|
+
children: node.items.map((pair) => convertPair(pair as Pair<any, any>, source)),
|
|
60
|
+
loc: loc(start, end),
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function convertPair(pair: Pair<any, any>, source: string): PropertyNode {
|
|
65
|
+
const key = pair.key as Scalar;
|
|
66
|
+
const value = pair.value;
|
|
67
|
+
|
|
68
|
+
const [keyStart, keyEnd] = getRange(key);
|
|
69
|
+
const [, valueEnd] = value ? getRange(value) : [keyEnd, keyEnd];
|
|
70
|
+
const pairEnd = valueEnd > keyEnd ? valueEnd : keyEnd;
|
|
71
|
+
|
|
72
|
+
return {
|
|
73
|
+
type: 'Property',
|
|
74
|
+
key: convertIdentifier(key),
|
|
75
|
+
value: value
|
|
76
|
+
? (convertNode(value, source) as ValueNode)
|
|
77
|
+
: ({ type: 'Literal', value: null, raw: 'null', loc: loc(keyEnd, keyEnd) } as LiteralNode),
|
|
78
|
+
loc: loc(keyStart, pairEnd),
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function convertIdentifier(node: Scalar): IdentifierNode {
|
|
83
|
+
const [start, end] = getRange(node);
|
|
84
|
+
const value = String(node.value ?? '');
|
|
85
|
+
return {
|
|
86
|
+
type: 'Identifier',
|
|
87
|
+
value,
|
|
88
|
+
raw: JSON.stringify(value),
|
|
89
|
+
loc: loc(start, end),
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function convertScalar(node: Scalar): LiteralNode {
|
|
94
|
+
const [start, end] = getRange(node);
|
|
95
|
+
const value = node.value as string | number | boolean | null;
|
|
96
|
+
return {
|
|
97
|
+
type: 'Literal',
|
|
98
|
+
value,
|
|
99
|
+
raw: JSON.stringify(value),
|
|
100
|
+
loc: loc(start, end),
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function convertSeq(node: YAMLSeq, source: string): ArrayNode {
|
|
105
|
+
const [start, end] = getRange(node);
|
|
106
|
+
return {
|
|
107
|
+
type: 'Array',
|
|
108
|
+
children: node.items.map((item) => convertNode(item, source) as ValueNode),
|
|
109
|
+
loc: loc(start, end),
|
|
110
|
+
};
|
|
111
|
+
}
|
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Access,
|
|
3
|
-
FilterEntry,
|
|
4
|
-
ObjectEntry,
|
|
5
|
-
TagEntry,
|
|
6
|
-
ThemeDocset,
|
|
7
|
-
Translations,
|
|
8
|
-
ReturnType,
|
|
9
|
-
} from './types';
|
|
10
|
-
import { memo } from './utils';
|
|
11
|
-
|
|
12
|
-
const toFilterEntry = (name: string): FilterEntry => ({ name });
|
|
13
|
-
|
|
14
|
-
const expandAliases = (entries: FilterEntry[]): FilterEntry[] => {
|
|
15
|
-
return entries.flatMap((entry) => {
|
|
16
|
-
const aliases: string[] = (entry as any).aliases ?? [];
|
|
17
|
-
return aliases.map((alias) => ({ ...entry, name: alias }));
|
|
18
|
-
});
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
const undocumentedFilters = [
|
|
22
|
-
'_online_store_editor_live_setting',
|
|
23
|
-
'addresses_url',
|
|
24
|
-
'app_block_path?',
|
|
25
|
-
'app_block_path_for',
|
|
26
|
-
'app_extension_path?',
|
|
27
|
-
'app_snippet_path?',
|
|
28
|
-
'cancel_customer_order_link',
|
|
29
|
-
'debug',
|
|
30
|
-
'delete_customer_address_link',
|
|
31
|
-
'dev_shop?',
|
|
32
|
-
'distance_from',
|
|
33
|
-
'edit_customer_address_link',
|
|
34
|
-
'encode_url_component',
|
|
35
|
-
'excerpt',
|
|
36
|
-
'format_code',
|
|
37
|
-
'global_block_type?',
|
|
38
|
-
'h',
|
|
39
|
-
'handle_from',
|
|
40
|
-
'installments_pricing',
|
|
41
|
-
'link_to_theme',
|
|
42
|
-
'login_button',
|
|
43
|
-
'login_url',
|
|
44
|
-
'logout_url',
|
|
45
|
-
'pad_spaces',
|
|
46
|
-
'paragraphize',
|
|
47
|
-
'recover_password_link',
|
|
48
|
-
'recover_url',
|
|
49
|
-
'register_url',
|
|
50
|
-
'registration_uuid_from',
|
|
51
|
-
'root_account_url',
|
|
52
|
-
'sentence',
|
|
53
|
-
'theme_url',
|
|
54
|
-
'unit',
|
|
55
|
-
'weight',
|
|
56
|
-
];
|
|
57
|
-
|
|
58
|
-
const undocumentedObjectEntryKeys = [
|
|
59
|
-
'locale',
|
|
60
|
-
'direction',
|
|
61
|
-
'skip_to_content_link',
|
|
62
|
-
'checkout_html_classes',
|
|
63
|
-
'checkout_stylesheets',
|
|
64
|
-
'checkout_scripts',
|
|
65
|
-
'content_for_logo',
|
|
66
|
-
'breadcrumb',
|
|
67
|
-
'order_summary_toggle',
|
|
68
|
-
'content_for_order_summary',
|
|
69
|
-
'alternative_payment_methods',
|
|
70
|
-
'content_for_footer',
|
|
71
|
-
'tracking_code',
|
|
72
|
-
];
|
|
73
|
-
|
|
74
|
-
const toObjectEntry = (name: string, access?: Access, returnType?: ReturnType[]): ObjectEntry => ({
|
|
75
|
-
name,
|
|
76
|
-
...(access && { access }),
|
|
77
|
-
...(returnType && { return_type: returnType }),
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
const undocumentedObjects = ['customer_address', 'product_variant'];
|
|
81
|
-
const legacyCheckoutEntries: ObjectEntry[] = undocumentedObjectEntryKeys.map((objectKey) =>
|
|
82
|
-
toObjectEntry(objectKey, { global: false, parents: [], template: [] }, [
|
|
83
|
-
{ type: 'string', name: '' },
|
|
84
|
-
]),
|
|
85
|
-
);
|
|
86
|
-
|
|
87
|
-
const toTagEntry = (name: string): TagEntry => ({ name });
|
|
88
|
-
const undocumentedTags = ['elsif', 'ifchanged', 'when', 'schema'];
|
|
89
|
-
|
|
90
|
-
export class AugmentedThemeDocset implements ThemeDocset {
|
|
91
|
-
constructor(private themeDocset: ThemeDocset) {}
|
|
92
|
-
graphQL = memo(async (): Promise<string | null> => {
|
|
93
|
-
return await this.themeDocset.graphQL();
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
public isAugmented = true;
|
|
97
|
-
|
|
98
|
-
filters = memo(async (): Promise<FilterEntry[]> => {
|
|
99
|
-
const officialFilters = await this.themeDocset.filters();
|
|
100
|
-
return [
|
|
101
|
-
...officialFilters,
|
|
102
|
-
...expandAliases(officialFilters),
|
|
103
|
-
...undocumentedFilters.map(toFilterEntry),
|
|
104
|
-
];
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
objects = memo(async (): Promise<ObjectEntry[]> => {
|
|
108
|
-
return [
|
|
109
|
-
...(await this.themeDocset.objects()),
|
|
110
|
-
...undocumentedObjects.map((obj) => toObjectEntry(obj)),
|
|
111
|
-
...legacyCheckoutEntries,
|
|
112
|
-
];
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
liquidDrops = memo(async (): Promise<ObjectEntry[]> => {
|
|
116
|
-
return (await this.themeDocset.objects()).filter((obj) => {
|
|
117
|
-
if (!obj.access) {
|
|
118
|
-
return true;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
if (obj.deprecated) {
|
|
122
|
-
return false;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
// objects that are accessible outside Global context
|
|
126
|
-
return !obj.access.global || (obj.access.global && obj.access.parents.length > 0);
|
|
127
|
-
});
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
tags = memo(async (): Promise<TagEntry[]> => {
|
|
131
|
-
return [...(await this.themeDocset.tags()), ...undocumentedTags.map(toTagEntry)];
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
systemTranslations = memo(async (): Promise<Translations> => {
|
|
135
|
-
return this.themeDocset.systemTranslations();
|
|
136
|
-
});
|
|
137
|
-
}
|
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest';
|
|
2
|
-
import { runLiquidCheck } from '../../test';
|
|
3
|
-
import { AppBlockMissingSchema } from './index';
|
|
4
|
-
|
|
5
|
-
describe('AppBlockMissingSchema', () => {
|
|
6
|
-
it('should report an error when schema tag is missing on a theme app extension (blocks only)', async () => {
|
|
7
|
-
const sourceCode = `
|
|
8
|
-
<footer class="footer">
|
|
9
|
-
{% for block in section.blocks %}
|
|
10
|
-
{% case block.type %}
|
|
11
|
-
{% when 'link' %}
|
|
12
|
-
<div class="link" {{ block.shopify_attributes }}>
|
|
13
|
-
{{ block.settings.linktext | link_to: block.settings.linkurl }}
|
|
14
|
-
</div>
|
|
15
|
-
|
|
16
|
-
{% when 'custom-text' %}
|
|
17
|
-
<div class="text" {{ block.shopify_attributes }}>
|
|
18
|
-
{{ block.settings.custom-text-field }}
|
|
19
|
-
</div>
|
|
20
|
-
{% endcase %}
|
|
21
|
-
{% endfor %}
|
|
22
|
-
</footer>
|
|
23
|
-
`;
|
|
24
|
-
|
|
25
|
-
const offenses = await runLiquidCheck(
|
|
26
|
-
AppBlockMissingSchema,
|
|
27
|
-
sourceCode,
|
|
28
|
-
'blocks/footer.liquid',
|
|
29
|
-
);
|
|
30
|
-
expect(offenses).to.have.lengthOf(1);
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
it('should not report an error when schema tag is missing on a snippet in a theme app extension )', async () => {
|
|
34
|
-
const sourceCode = `
|
|
35
|
-
<footer class="footer">
|
|
36
|
-
{% for block in section.blocks %}
|
|
37
|
-
{% case block.type %}
|
|
38
|
-
{% when 'link' %}
|
|
39
|
-
<div class="link" {{ block.shopify_attributes }}>
|
|
40
|
-
{{ block.settings.linktext | link_to: block.settings.linkurl }}
|
|
41
|
-
</div>
|
|
42
|
-
|
|
43
|
-
{% when 'custom-text' %}
|
|
44
|
-
<div class="text" {{ block.shopify_attributes }}>
|
|
45
|
-
{{ block.settings.custom-text-field }}
|
|
46
|
-
</div>
|
|
47
|
-
{% endcase %}
|
|
48
|
-
{% endfor %}
|
|
49
|
-
</footer>
|
|
50
|
-
`;
|
|
51
|
-
|
|
52
|
-
const offenses = await runLiquidCheck(
|
|
53
|
-
AppBlockMissingSchema,
|
|
54
|
-
sourceCode,
|
|
55
|
-
'app/views/partials/footer.liquid',
|
|
56
|
-
);
|
|
57
|
-
expect(offenses).to.have.lengthOf(0);
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
it('should not report when the schema is present on a theme app extension', async () => {
|
|
61
|
-
const sourceCode = `
|
|
62
|
-
<footer class="footer">
|
|
63
|
-
{% for block in section.blocks %}
|
|
64
|
-
{% case block.type %}
|
|
65
|
-
{% when 'link' %}
|
|
66
|
-
<div class="link" {{ block.shopify_attributes }}>
|
|
67
|
-
{{ block.settings.linktext | link_to: block.settings.linkurl }}
|
|
68
|
-
</div>
|
|
69
|
-
|
|
70
|
-
{% when 'custom-text' %}
|
|
71
|
-
<div class="text" {{ block.shopify_attributes }}>
|
|
72
|
-
{{ block.settings.custom-text-field }}
|
|
73
|
-
</div>
|
|
74
|
-
{% endcase %}
|
|
75
|
-
{% endfor %}
|
|
76
|
-
</footer>
|
|
77
|
-
|
|
78
|
-
{% schema %}
|
|
79
|
-
{
|
|
80
|
-
"name": "Footer",
|
|
81
|
-
"max_blocks": 8,
|
|
82
|
-
"blocks": [
|
|
83
|
-
{
|
|
84
|
-
"type": "link",
|
|
85
|
-
"name": "Link",
|
|
86
|
-
"settings": [
|
|
87
|
-
{
|
|
88
|
-
"id": "linkurl",
|
|
89
|
-
"type": "url",
|
|
90
|
-
"label": "URL link"
|
|
91
|
-
},
|
|
92
|
-
{
|
|
93
|
-
"id": "linktext",
|
|
94
|
-
"type": "text",
|
|
95
|
-
"label": "Link text"
|
|
96
|
-
}
|
|
97
|
-
]
|
|
98
|
-
},
|
|
99
|
-
{
|
|
100
|
-
"type": "custom-text",
|
|
101
|
-
"name": "Custom Text",
|
|
102
|
-
"settings": [
|
|
103
|
-
{
|
|
104
|
-
"id": "custom-text-field",
|
|
105
|
-
"type": "textarea",
|
|
106
|
-
"label": "Text"
|
|
107
|
-
}
|
|
108
|
-
]
|
|
109
|
-
}
|
|
110
|
-
]
|
|
111
|
-
}
|
|
112
|
-
{% endschema %}`;
|
|
113
|
-
|
|
114
|
-
const offenses = await runLiquidCheck(
|
|
115
|
-
AppBlockMissingSchema,
|
|
116
|
-
sourceCode,
|
|
117
|
-
'blocks/footer.liquid',
|
|
118
|
-
);
|
|
119
|
-
expect(offenses).to.have.lengthOf(0);
|
|
120
|
-
});
|
|
121
|
-
});
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { ConfigTarget, LiquidCheckDefinition, Severity, SourceCodeType } from '../../types';
|
|
2
|
-
|
|
3
|
-
export const AppBlockMissingSchema: LiquidCheckDefinition = {
|
|
4
|
-
meta: {
|
|
5
|
-
code: 'AppBlockMissingSchema',
|
|
6
|
-
name: 'Missing schema definitions in theme app extensions app blocks should be avoided',
|
|
7
|
-
docs: {
|
|
8
|
-
description: 'Report missing schema definitions in theme app extensions app blocks',
|
|
9
|
-
recommended: true,
|
|
10
|
-
url: 'https://shopify.dev/docs/storefronts/themes/tools/theme-check/checks/app-block-missing-schema',
|
|
11
|
-
},
|
|
12
|
-
severity: Severity.ERROR,
|
|
13
|
-
type: SourceCodeType.LiquidHtml,
|
|
14
|
-
schema: {},
|
|
15
|
-
targets: [ConfigTarget.ThemeAppExtension],
|
|
16
|
-
},
|
|
17
|
-
|
|
18
|
-
create(context) {
|
|
19
|
-
let foundSchema = false;
|
|
20
|
-
const relativePath = context.toRelativePath(context.file.uri);
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Theme app extension blocks are the only types of files that can have a
|
|
24
|
-
* schema defined in them.
|
|
25
|
-
*/
|
|
26
|
-
if (!relativePath.startsWith('blocks/')) {
|
|
27
|
-
return {};
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
return {
|
|
31
|
-
async LiquidRawTag(node) {
|
|
32
|
-
if (node.name == 'schema') foundSchema = true;
|
|
33
|
-
},
|
|
34
|
-
|
|
35
|
-
async onCodePathEnd() {
|
|
36
|
-
if (!foundSchema) {
|
|
37
|
-
context.report({
|
|
38
|
-
message: `The schema does not exist`,
|
|
39
|
-
startIndex: 0,
|
|
40
|
-
endIndex: 0,
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
},
|
|
44
|
-
};
|
|
45
|
-
},
|
|
46
|
-
};
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import { runLiquidCheck } from '../../test';
|
|
3
|
-
import { ForbiddenTag, AppBlockValidTags } from './index';
|
|
4
|
-
|
|
5
|
-
const blocksFilePath = 'blocks/app.liquid';
|
|
6
|
-
|
|
7
|
-
describe('Module: AppBlockValidTags', () => {
|
|
8
|
-
it('should report an offense when the forbidden tag is used in blocks directory liquid file', async () => {
|
|
9
|
-
const tags = ['include', 'layout', 'section', 'sections'];
|
|
10
|
-
for (const tag of tags) {
|
|
11
|
-
const sourceCode = `
|
|
12
|
-
{% ${tag} 'test' %}
|
|
13
|
-
{% schema %}
|
|
14
|
-
{ }
|
|
15
|
-
{% endschema %}
|
|
16
|
-
`;
|
|
17
|
-
|
|
18
|
-
const offenses = await runLiquidCheck(AppBlockValidTags, sourceCode, blocksFilePath);
|
|
19
|
-
|
|
20
|
-
const expectedStart = {
|
|
21
|
-
index: 9,
|
|
22
|
-
line: 1,
|
|
23
|
-
character: 8,
|
|
24
|
-
};
|
|
25
|
-
const tagEndOffset = 13;
|
|
26
|
-
const endOffset = tag.length + tagEndOffset;
|
|
27
|
-
|
|
28
|
-
const expectedEnd = {
|
|
29
|
-
index: expectedStart.index + endOffset,
|
|
30
|
-
line: expectedStart.line,
|
|
31
|
-
character: expectedStart.character + endOffset,
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
expect(offenses).to.have.length(1);
|
|
35
|
-
expect(offenses).to.containOffense({
|
|
36
|
-
check: AppBlockValidTags.meta.code,
|
|
37
|
-
message: `Theme app extension blocks cannot contain '${tag}' tags`,
|
|
38
|
-
uri: 'file:///blocks/app.liquid',
|
|
39
|
-
severity: 0,
|
|
40
|
-
start: expectedStart,
|
|
41
|
-
end: expectedEnd,
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
it('should report an offense when the forbidden tag is used with an end tag in blocks directory liquid file', async () => {
|
|
47
|
-
const tags = ['javascript', 'stylesheet'];
|
|
48
|
-
for (const tag of tags) {
|
|
49
|
-
const sourceCode = `
|
|
50
|
-
{% ${tag} %}
|
|
51
|
-
{% end${tag} %}
|
|
52
|
-
{% schema %}
|
|
53
|
-
{ }
|
|
54
|
-
{% endschema %}
|
|
55
|
-
`;
|
|
56
|
-
|
|
57
|
-
const offenses = await runLiquidCheck(AppBlockValidTags, sourceCode, blocksFilePath);
|
|
58
|
-
|
|
59
|
-
const expectedStart = {
|
|
60
|
-
index: 9,
|
|
61
|
-
line: 1,
|
|
62
|
-
character: 8,
|
|
63
|
-
};
|
|
64
|
-
const expectedEnd = {
|
|
65
|
-
index: expectedStart.index + tag.length + 34,
|
|
66
|
-
line: 2,
|
|
67
|
-
character: expectedStart.character + tag.length + 9,
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
expect(offenses).to.have.length(1);
|
|
71
|
-
expect(offenses).to.containOffense({
|
|
72
|
-
check: AppBlockValidTags.meta.code,
|
|
73
|
-
message: `Theme app extension blocks cannot contain '${tag}' tags`,
|
|
74
|
-
uri: 'file:///blocks/app.liquid',
|
|
75
|
-
severity: 0,
|
|
76
|
-
start: expectedStart,
|
|
77
|
-
end: expectedEnd,
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
it('should contain specifically the following forbidden tags', async () => {
|
|
83
|
-
const actualTagValues = Object.values(ForbiddenTag);
|
|
84
|
-
const expectedTagValues = [
|
|
85
|
-
'javascript',
|
|
86
|
-
'stylesheet',
|
|
87
|
-
'include',
|
|
88
|
-
'layout',
|
|
89
|
-
'section',
|
|
90
|
-
'sections',
|
|
91
|
-
];
|
|
92
|
-
|
|
93
|
-
expectedTagValues.forEach((tag) => expect(actualTagValues).toContain(tag));
|
|
94
|
-
expect(actualTagValues.length).toBe(expectedTagValues.length);
|
|
95
|
-
});
|
|
96
|
-
});
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import { LiquidRawTag, LiquidTag } from '@platformos/liquid-html-parser';
|
|
2
|
-
import { ConfigTarget, LiquidCheckDefinition, Severity, SourceCodeType } from '../../types';
|
|
3
|
-
|
|
4
|
-
export enum ForbiddenTag {
|
|
5
|
-
JavaScript = 'javascript',
|
|
6
|
-
StyleSheet = 'stylesheet',
|
|
7
|
-
Include = 'include',
|
|
8
|
-
Layout = 'layout',
|
|
9
|
-
Section = 'section',
|
|
10
|
-
Sections = 'sections',
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
const isForbiddenTag = (value: string): value is ForbiddenTag => {
|
|
14
|
-
return Object.values(ForbiddenTag).includes(value as ForbiddenTag);
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
const buildErrorMessage = (tag: ForbiddenTag) =>
|
|
18
|
-
`Theme app extension blocks cannot contain '${tag}' tags`;
|
|
19
|
-
|
|
20
|
-
export const AppBlockValidTags: LiquidCheckDefinition = {
|
|
21
|
-
meta: {
|
|
22
|
-
code: 'AppBlockValidTags',
|
|
23
|
-
name: 'App Block Valid Tags',
|
|
24
|
-
docs: {
|
|
25
|
-
description:
|
|
26
|
-
'Identifies forbidden Liquid tags in theme app extension app block and app embed block code.',
|
|
27
|
-
url: 'https://shopify.dev/docs/storefronts/themes/tools/theme-check/checks/app-block-valid-tags',
|
|
28
|
-
recommended: false,
|
|
29
|
-
},
|
|
30
|
-
type: SourceCodeType.LiquidHtml,
|
|
31
|
-
severity: Severity.ERROR,
|
|
32
|
-
schema: {},
|
|
33
|
-
targets: [ConfigTarget.ThemeAppExtension],
|
|
34
|
-
},
|
|
35
|
-
|
|
36
|
-
create(context) {
|
|
37
|
-
const handleForbiddenTags = async (node: LiquidTag | LiquidRawTag) => {
|
|
38
|
-
if (isForbiddenTag(node.name)) {
|
|
39
|
-
// When a forbidden tag is used to define a block section
|
|
40
|
-
// with an end tag, highlight the whole section
|
|
41
|
-
const endIndex = node.blockEndPosition ? node.blockEndPosition.end : node.position.end;
|
|
42
|
-
const startIndex = node.blockStartPosition.start;
|
|
43
|
-
const message = buildErrorMessage(node.name);
|
|
44
|
-
|
|
45
|
-
return context.report({ message, startIndex, endIndex });
|
|
46
|
-
}
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
return {
|
|
50
|
-
LiquidRawTag: handleForbiddenTags,
|
|
51
|
-
LiquidTag: handleForbiddenTags,
|
|
52
|
-
};
|
|
53
|
-
},
|
|
54
|
-
};
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import { runLiquidCheck, highlightedOffenses } from '../../test';
|
|
3
|
-
import { AssetPreload } from './index';
|
|
4
|
-
|
|
5
|
-
describe('Module: AssetPreload', () => {
|
|
6
|
-
it('no offense with link element', async () => {
|
|
7
|
-
const sourceCode = `
|
|
8
|
-
<link href="a.css" rel="stylesheet">
|
|
9
|
-
<link href="b.com" rel="preconnect">
|
|
10
|
-
`;
|
|
11
|
-
|
|
12
|
-
const offenses = await runLiquidCheck(AssetPreload, sourceCode);
|
|
13
|
-
expect(offenses).to.have.lengthOf(0);
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
it('reports stylesheet preloading', async () => {
|
|
17
|
-
const sourceCode = `
|
|
18
|
-
<link href="a.css" rel="preload" as="style">
|
|
19
|
-
`;
|
|
20
|
-
|
|
21
|
-
const offenses = await runLiquidCheck(AssetPreload, sourceCode);
|
|
22
|
-
expect(offenses).to.have.lengthOf(1);
|
|
23
|
-
expect(offenses[0].message).to.equal(
|
|
24
|
-
'For better performance, prefer using the preload argument of the stylesheet_tag filter',
|
|
25
|
-
);
|
|
26
|
-
|
|
27
|
-
const highlights = highlightedOffenses({ 'file.liquid': sourceCode }, offenses);
|
|
28
|
-
expect(highlights).to.eql([`<link href="a.css" rel="preload" as="style">`]);
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
it('reports image preloading', async () => {
|
|
32
|
-
const sourceCode = `
|
|
33
|
-
<link href="a.png" rel="preload" as="image">
|
|
34
|
-
`;
|
|
35
|
-
|
|
36
|
-
const offenses = await runLiquidCheck(AssetPreload, sourceCode);
|
|
37
|
-
expect(offenses).to.have.lengthOf(1);
|
|
38
|
-
expect(offenses[0].message).to.equal(
|
|
39
|
-
'For better performance, prefer using the preload argument of the image_tag filter',
|
|
40
|
-
);
|
|
41
|
-
|
|
42
|
-
const highlights = highlightedOffenses({ 'file.liquid': sourceCode }, offenses);
|
|
43
|
-
expect(highlights).to.eql([`<link href="a.png" rel="preload" as="image">`]);
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
it('reports general preloading', async () => {
|
|
47
|
-
const sourceCode = `
|
|
48
|
-
<link href="a.js" rel="preload" as="script">
|
|
49
|
-
`;
|
|
50
|
-
|
|
51
|
-
const offenses = await runLiquidCheck(AssetPreload, sourceCode);
|
|
52
|
-
expect(offenses).to.have.lengthOf(1);
|
|
53
|
-
expect(offenses[0].message).to.equal(
|
|
54
|
-
'For better performance, prefer using the preload_tag filter',
|
|
55
|
-
);
|
|
56
|
-
|
|
57
|
-
const highlights = highlightedOffenses({ 'file.liquid': sourceCode }, offenses);
|
|
58
|
-
expect(highlights).to.eql([`<link href="a.js" rel="preload" as="script">`]);
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
it('should report offenses for manual preloading of assets', async () => {
|
|
62
|
-
const sourceCode = `
|
|
63
|
-
<link href="{{ 'script.js' | asset_url }}" rel="preload" as="script">
|
|
64
|
-
<link href="{{ 'style.css' | asset_url }}" rel="preload" as="style">
|
|
65
|
-
<link href="{{ 'image.png' | asset_url }}" rel="preload" as="image">
|
|
66
|
-
`;
|
|
67
|
-
|
|
68
|
-
const offenses = await runLiquidCheck(AssetPreload, sourceCode);
|
|
69
|
-
expect(offenses).to.have.lengthOf(3);
|
|
70
|
-
|
|
71
|
-
const highlights = highlightedOffenses({ 'file.liquid': sourceCode }, offenses);
|
|
72
|
-
expect(highlights).to.eql([
|
|
73
|
-
`<link href="{{ 'script.js' | asset_url }}" rel="preload" as="script">`,
|
|
74
|
-
`<link href="{{ 'style.css' | asset_url }}" rel="preload" as="style">`,
|
|
75
|
-
`<link href="{{ 'image.png' | asset_url }}" rel="preload" as="image">`,
|
|
76
|
-
]);
|
|
77
|
-
});
|
|
78
|
-
});
|