@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.
Files changed (304) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/AugmentedPlatformOSDocset.d.ts +11 -0
  3. package/dist/AugmentedPlatformOSDocset.js +81 -0
  4. package/dist/AugmentedPlatformOSDocset.js.map +1 -0
  5. package/dist/JSONValidator.js +1 -1
  6. package/dist/JSONValidator.js.map +1 -1
  7. package/dist/checks/deprecated-filter/index.js +4 -41
  8. package/dist/checks/deprecated-filter/index.js.map +1 -1
  9. package/dist/checks/deprecated-tag/index.js +21 -22
  10. package/dist/checks/deprecated-tag/index.js.map +1 -1
  11. package/dist/checks/duplicate-function-arguments/index.js +1 -1
  12. package/dist/checks/duplicate-function-arguments/index.js.map +1 -1
  13. package/dist/checks/duplicate-render-partial-arguments/index.js +1 -1
  14. package/dist/checks/duplicate-render-partial-arguments/index.js.map +1 -1
  15. package/dist/checks/graphql/index.js +1 -1
  16. package/dist/checks/graphql/index.js.map +1 -1
  17. package/dist/checks/img-width-and-height/index.js +1 -1
  18. package/dist/checks/img-width-and-height/index.js.map +1 -1
  19. package/dist/checks/index.d.ts +3 -3
  20. package/dist/checks/index.js +4 -79
  21. package/dist/checks/index.js.map +1 -1
  22. package/dist/checks/json-syntax-error/index.js +1 -1
  23. package/dist/checks/json-syntax-error/index.js.map +1 -1
  24. package/dist/checks/liquid-html-syntax-error/index.js +2 -2
  25. package/dist/checks/liquid-html-syntax-error/index.js.map +1 -1
  26. package/dist/checks/matching-translations/index.d.ts +2 -2
  27. package/dist/checks/matching-translations/index.js +20 -31
  28. package/dist/checks/matching-translations/index.js.map +1 -1
  29. package/dist/checks/metadata-params/index.js +6 -3
  30. package/dist/checks/metadata-params/index.js.map +1 -1
  31. package/dist/checks/missing-asset/index.js +1 -1
  32. package/dist/checks/missing-asset/index.js.map +1 -1
  33. package/dist/checks/missing-partial/index.d.ts +6 -0
  34. package/dist/checks/missing-partial/index.js +70 -0
  35. package/dist/checks/missing-partial/index.js.map +1 -0
  36. package/dist/checks/orphaned-partial/index.js +4 -4
  37. package/dist/checks/orphaned-partial/index.js.map +1 -1
  38. package/dist/checks/parser-blocking-script/index.js +10 -36
  39. package/dist/checks/parser-blocking-script/index.js.map +1 -1
  40. package/dist/checks/parser-blocking-script/suggestions.d.ts +1 -2
  41. package/dist/checks/parser-blocking-script/suggestions.js +1 -11
  42. package/dist/checks/parser-blocking-script/suggestions.js.map +1 -1
  43. package/dist/checks/reserved-doc-param-names/index.js +6 -5
  44. package/dist/checks/reserved-doc-param-names/index.js.map +1 -1
  45. package/dist/checks/translation-key-exists/index.js +1 -1
  46. package/dist/checks/translation-key-exists/index.js.map +1 -1
  47. package/dist/checks/unclosed-html-element/index.js +5 -1
  48. package/dist/checks/unclosed-html-element/index.js.map +1 -1
  49. package/dist/checks/undefined-object/index.js +7 -30
  50. package/dist/checks/undefined-object/index.js.map +1 -1
  51. package/dist/checks/unique-doc-param-names/index.js +1 -1
  52. package/dist/checks/unique-doc-param-names/index.js.map +1 -1
  53. package/dist/checks/unknown-filter/index.js +3 -3
  54. package/dist/checks/unknown-filter/index.js.map +1 -1
  55. package/dist/checks/unknown-property/index.js +1 -1
  56. package/dist/checks/unknown-property/index.js.map +1 -1
  57. package/dist/checks/unrecognized-render-partial-arguments/index.js +2 -2
  58. package/dist/checks/unrecognized-render-partial-arguments/index.js.map +1 -1
  59. package/dist/checks/unused-assign/index.js +1 -1
  60. package/dist/checks/unused-assign/index.js.map +1 -1
  61. package/dist/checks/unused-doc-param/index.js +1 -1
  62. package/dist/checks/unused-doc-param/index.js.map +1 -1
  63. package/dist/checks/utils.js +1 -1
  64. package/dist/checks/utils.js.map +1 -1
  65. package/dist/checks/valid-content-for-arguments/index.js +1 -1
  66. package/dist/checks/valid-content-for-arguments/index.js.map +1 -1
  67. package/dist/checks/valid-doc-param-types/index.js +4 -4
  68. package/dist/checks/valid-doc-param-types/index.js.map +1 -1
  69. package/dist/checks/valid-html-translation/index.d.ts +2 -2
  70. package/dist/checks/valid-html-translation/index.js +4 -4
  71. package/dist/checks/valid-html-translation/index.js.map +1 -1
  72. package/dist/checks/valid-json/index.js +1 -1
  73. package/dist/checks/valid-json/index.js.map +1 -1
  74. package/dist/checks/valid-render-partial-argument-types/index.js +2 -2
  75. package/dist/checks/valid-render-partial-argument-types/index.js.map +1 -1
  76. package/dist/checks/variable-name/index.js +1 -1
  77. package/dist/checks/variable-name/index.js.map +1 -1
  78. package/dist/context-utils.d.ts +2 -7
  79. package/dist/context-utils.js +39 -109
  80. package/dist/context-utils.js.map +1 -1
  81. package/dist/disabled-checks/index.js +4 -2
  82. package/dist/disabled-checks/index.js.map +1 -1
  83. package/dist/find-root.d.ts +7 -10
  84. package/dist/find-root.js +10 -17
  85. package/dist/find-root.js.map +1 -1
  86. package/dist/fixes/autofix.d.ts +4 -4
  87. package/dist/fixes/autofix.js +2 -2
  88. package/dist/fixes/autofix.js.map +1 -1
  89. package/dist/fixes/correctors/index.js +4 -0
  90. package/dist/fixes/correctors/index.js.map +1 -1
  91. package/dist/index.d.ts +4 -5
  92. package/dist/index.js +34 -17
  93. package/dist/index.js.map +1 -1
  94. package/dist/jsonc/parse.d.ts +1 -1
  95. package/dist/jsonc/parse.js +1 -1
  96. package/dist/liquid-doc/arguments.d.ts +7 -8
  97. package/dist/liquid-doc/arguments.js +20 -28
  98. package/dist/liquid-doc/arguments.js.map +1 -1
  99. package/dist/liquid-doc/liquidDoc.d.ts +1 -1
  100. package/dist/liquid-doc/liquidDoc.js.map +1 -1
  101. package/dist/liquid-doc/utils.d.ts +1 -1
  102. package/dist/liquid-doc/utils.js +4 -3
  103. package/dist/liquid-doc/utils.js.map +1 -1
  104. package/dist/path.d.ts +1 -0
  105. package/dist/path.js +5 -1
  106. package/dist/path.js.map +1 -1
  107. package/dist/test/MockApp.d.ts +16 -0
  108. package/dist/test/MockApp.js +16 -0
  109. package/dist/test/MockApp.js.map +1 -0
  110. package/dist/test/MockFileSystem.d.ts +3 -3
  111. package/dist/test/MockFileSystem.js +6 -6
  112. package/dist/test/MockFileSystem.js.map +1 -1
  113. package/dist/test/index.d.ts +1 -1
  114. package/dist/test/index.js +1 -1
  115. package/dist/test/index.js.map +1 -1
  116. package/dist/test/test-helper.d.ts +10 -9
  117. package/dist/test/test-helper.js +15 -106
  118. package/dist/test/test-helper.js.map +1 -1
  119. package/dist/to-source-code.d.ts +4 -3
  120. package/dist/to-source-code.js +20 -0
  121. package/dist/to-source-code.js.map +1 -1
  122. package/dist/tsconfig.tsbuildinfo +1 -1
  123. package/dist/types/platformos-liquid-docs.d.ts +128 -0
  124. package/dist/types/platformos-liquid-docs.js +3 -0
  125. package/dist/types/platformos-liquid-docs.js.map +1 -0
  126. package/dist/types/schemas/index.d.ts +0 -2
  127. package/dist/types/schemas/index.js.map +1 -1
  128. package/dist/types.d.ts +18 -67
  129. package/dist/types.js +3 -5
  130. package/dist/types.js.map +1 -1
  131. package/dist/utils/file-utils.js +1 -2
  132. package/dist/utils/file-utils.js.map +1 -1
  133. package/dist/utils/index.d.ts +0 -1
  134. package/dist/utils/index.js +0 -1
  135. package/dist/utils/index.js.map +1 -1
  136. package/dist/yaml/parse.d.ts +5 -0
  137. package/dist/yaml/parse.js +94 -0
  138. package/dist/yaml/parse.js.map +1 -0
  139. package/package.json +9 -9
  140. package/src/{AugmentedThemeDocset.spec.ts → AugmentedPlatformOSDocset.spec.ts} +47 -34
  141. package/src/AugmentedPlatformOSDocset.ts +89 -0
  142. package/src/JSONValidator.ts +1 -1
  143. package/src/checks/deprecated-filter/index.spec.ts +76 -248
  144. package/src/checks/deprecated-filter/index.ts +5 -53
  145. package/src/checks/deprecated-tag/index.spec.ts +85 -34
  146. package/src/checks/deprecated-tag/index.ts +27 -22
  147. package/src/checks/duplicate-function-arguments/index.ts +1 -1
  148. package/src/checks/duplicate-render-partial-arguments/index.ts +1 -1
  149. package/src/checks/graphql/index.ts +1 -1
  150. package/src/checks/img-width-and-height/index.ts +1 -1
  151. package/src/checks/index.ts +11 -80
  152. package/src/checks/invalid-hash-assign-target/index.spec.ts +14 -14
  153. package/src/checks/json-syntax-error/index.ts +1 -1
  154. package/src/checks/liquid-html-syntax-error/checks/InvalidBooleanExpression.spec.ts +0 -11
  155. package/src/checks/liquid-html-syntax-error/checks/InvalidLoopArguments.spec.ts +1 -2
  156. package/src/checks/liquid-html-syntax-error/index.spec.ts +1 -6
  157. package/src/checks/liquid-html-syntax-error/index.ts +2 -2
  158. package/src/checks/matching-translations/index.spec.ts +89 -346
  159. package/src/checks/matching-translations/index.ts +24 -35
  160. package/src/checks/metadata-params/index.ts +5 -7
  161. package/src/checks/missing-asset/index.ts +1 -1
  162. package/src/checks/{missing-template → missing-partial}/index.spec.ts +6 -6
  163. package/src/checks/{missing-template → missing-partial}/index.ts +6 -20
  164. package/src/checks/orphaned-partial/index.ts +3 -3
  165. package/src/checks/parser-blocking-script/index.spec.ts +0 -118
  166. package/src/checks/parser-blocking-script/index.ts +3 -33
  167. package/src/checks/parser-blocking-script/suggestions.ts +1 -28
  168. package/src/checks/translation-key-exists/index.ts +1 -1
  169. package/src/checks/unclosed-html-element/index.ts +5 -1
  170. package/src/checks/undefined-object/index.spec.ts +3 -109
  171. package/src/checks/undefined-object/index.ts +8 -33
  172. package/src/checks/unique-doc-param-names/index.ts +1 -1
  173. package/src/checks/unknown-filter/index.spec.ts +2 -2
  174. package/src/checks/unknown-filter/index.ts +3 -3
  175. package/src/checks/unknown-property/index.ts +1 -1
  176. package/src/checks/unrecognized-render-partial-arguments/index.spec.ts +5 -5
  177. package/src/checks/unrecognized-render-partial-arguments/index.ts +2 -5
  178. package/src/checks/unused-assign/index.spec.ts +0 -30
  179. package/src/checks/unused-assign/index.ts +1 -1
  180. package/src/checks/unused-doc-param/index.ts +1 -1
  181. package/src/checks/utils.ts +1 -1
  182. package/src/checks/valid-doc-param-types/index.ts +4 -4
  183. package/src/checks/valid-html-translation/index.spec.ts +42 -32
  184. package/src/checks/valid-html-translation/index.ts +7 -7
  185. package/src/checks/valid-json/index.ts +1 -1
  186. package/src/checks/valid-render-partial-argument-types/index.ts +2 -5
  187. package/src/checks/variable-name/index.ts +1 -1
  188. package/src/context-utils.spec.ts +49 -77
  189. package/src/context-utils.ts +39 -128
  190. package/src/disabled-checks/index.spec.ts +35 -0
  191. package/src/disabled-checks/index.ts +4 -2
  192. package/src/find-root.ts +12 -22
  193. package/src/fixes/autofix.spec.ts +2 -2
  194. package/src/fixes/autofix.ts +4 -4
  195. package/src/fixes/correctors/index.ts +4 -0
  196. package/src/ignore.spec.ts +0 -1
  197. package/src/index.ts +33 -21
  198. package/src/jsonc/parse.ts +1 -1
  199. package/src/liquid-doc/arguments.spec.ts +19 -45
  200. package/src/liquid-doc/arguments.ts +26 -39
  201. package/src/liquid-doc/liquidDoc.ts +1 -2
  202. package/src/liquid-doc/utils.ts +4 -3
  203. package/src/path.ts +1 -0
  204. package/src/test/{MockTheme.ts → MockApp.ts} +1 -1
  205. package/src/test/MockFileSystem.ts +9 -6
  206. package/src/test/index.ts +1 -1
  207. package/src/test/test-helper.ts +29 -127
  208. package/src/to-source-code.ts +20 -1
  209. package/src/types/{theme-liquid-docs.ts → platformos-liquid-docs.ts} +8 -13
  210. package/src/types/schemas/index.ts +0 -2
  211. package/src/types.ts +21 -92
  212. package/src/utils/file-utils.ts +0 -1
  213. package/src/utils/index.ts +0 -1
  214. package/src/yaml/parse.ts +111 -0
  215. package/src/AugmentedThemeDocset.ts +0 -137
  216. package/src/checks/app-block-missing-schema/index.spec.ts +0 -121
  217. package/src/checks/app-block-missing-schema/index.ts +0 -46
  218. package/src/checks/app-block-valid-tags/index.spec.ts +0 -96
  219. package/src/checks/app-block-valid-tags/index.ts +0 -54
  220. package/src/checks/asset-preload/index.spec.ts +0 -78
  221. package/src/checks/asset-preload/index.ts +0 -65
  222. package/src/checks/asset-size-app-block-css/index.spec.ts +0 -88
  223. package/src/checks/asset-size-app-block-css/index.ts +0 -78
  224. package/src/checks/asset-size-app-block-javascript/index.spec.ts +0 -66
  225. package/src/checks/asset-size-app-block-javascript/index.ts +0 -78
  226. package/src/checks/asset-size-css/index.spec.ts +0 -166
  227. package/src/checks/asset-size-css/index.ts +0 -160
  228. package/src/checks/asset-size-javascript/index.spec.ts +0 -184
  229. package/src/checks/asset-size-javascript/index.ts +0 -144
  230. package/src/checks/block-id-usage/index.spec.ts +0 -76
  231. package/src/checks/block-id-usage/index.ts +0 -72
  232. package/src/checks/cdn-preconnect/index.spec.ts +0 -40
  233. package/src/checks/cdn-preconnect/index.ts +0 -43
  234. package/src/checks/content-for-header-modification/index.spec.ts +0 -65
  235. package/src/checks/content-for-header-modification/index.ts +0 -72
  236. package/src/checks/deprecate-bgsizes/index.spec.ts +0 -41
  237. package/src/checks/deprecate-bgsizes/index.ts +0 -49
  238. package/src/checks/deprecate-lazysizes/index.spec.ts +0 -26
  239. package/src/checks/deprecate-lazysizes/index.ts +0 -58
  240. package/src/checks/deprecated-filter/fixes.ts +0 -264
  241. package/src/checks/deprecated-fonts-on-sections-and-blocks/deprecated-fonts-data.ts +0 -1343
  242. package/src/checks/deprecated-fonts-on-sections-and-blocks/index.spec.ts +0 -613
  243. package/src/checks/deprecated-fonts-on-sections-and-blocks/index.ts +0 -284
  244. package/src/checks/deprecated-fonts-on-settings-schema/index.spec.ts +0 -102
  245. package/src/checks/deprecated-fonts-on-settings-schema/index.ts +0 -66
  246. package/src/checks/duplicate-content-for-arguments/index.spec.ts +0 -98
  247. package/src/checks/duplicate-content-for-arguments/index.ts +0 -43
  248. package/src/checks/empty-block-content/index.spec.ts +0 -117
  249. package/src/checks/empty-block-content/index.ts +0 -60
  250. package/src/checks/hardcoded-routes/index.spec.ts +0 -58
  251. package/src/checks/hardcoded-routes/index.ts +0 -100
  252. package/src/checks/json-missing-block/index.spec.ts +0 -435
  253. package/src/checks/json-missing-block/index.ts +0 -56
  254. package/src/checks/json-missing-block/missing-block-utils.ts +0 -147
  255. package/src/checks/liquid-free-settings/index.spec.ts +0 -180
  256. package/src/checks/liquid-free-settings/index.ts +0 -79
  257. package/src/checks/missing-content-for-arguments/index.spec.ts +0 -144
  258. package/src/checks/missing-content-for-arguments/index.ts +0 -46
  259. package/src/checks/pagination-size/index.spec.ts +0 -158
  260. package/src/checks/pagination-size/index.ts +0 -104
  261. package/src/checks/remote-asset/index.spec.ts +0 -280
  262. package/src/checks/remote-asset/index.ts +0 -238
  263. package/src/checks/reserved-doc-param-names/index.spec.ts +0 -62
  264. package/src/checks/reserved-doc-param-names/index.ts +0 -57
  265. package/src/checks/schema-presets-block-order/index.spec.ts +0 -344
  266. package/src/checks/schema-presets-block-order/index.ts +0 -154
  267. package/src/checks/schema-presets-static-blocks/index.spec.ts +0 -145
  268. package/src/checks/schema-presets-static-blocks/index.ts +0 -126
  269. package/src/checks/static-stylesheet-and-javascript-tags/index.spec.ts +0 -257
  270. package/src/checks/static-stylesheet-and-javascript-tags/index.ts +0 -48
  271. package/src/checks/unique-settings-id/index.spec.ts +0 -24
  272. package/src/checks/unique-settings-id/index.ts +0 -84
  273. package/src/checks/unique-settings-id/test-data.ts +0 -1191
  274. package/src/checks/unique-static-block-id/index.spec.ts +0 -55
  275. package/src/checks/unique-static-block-id/index.ts +0 -60
  276. package/src/checks/unrecognized-content-for-arguments/index.spec.ts +0 -145
  277. package/src/checks/unrecognized-content-for-arguments/index.ts +0 -55
  278. package/src/checks/valid-block-target/index.spec.ts +0 -1396
  279. package/src/checks/valid-block-target/index.ts +0 -142
  280. package/src/checks/valid-content-for-argument-types/index.spec.ts +0 -382
  281. package/src/checks/valid-content-for-argument-types/index.ts +0 -42
  282. package/src/checks/valid-content-for-arguments/index.spec.ts +0 -107
  283. package/src/checks/valid-content-for-arguments/index.ts +0 -98
  284. package/src/checks/valid-local-blocks/index.spec.ts +0 -286
  285. package/src/checks/valid-local-blocks/index.ts +0 -100
  286. package/src/checks/valid-local-blocks/valid-block-utils.ts +0 -97
  287. package/src/checks/valid-schema/index.spec.ts +0 -174
  288. package/src/checks/valid-schema/index.ts +0 -41
  289. package/src/checks/valid-schema-name/index.spec.ts +0 -112
  290. package/src/checks/valid-schema-name/index.ts +0 -75
  291. package/src/checks/valid-settings-key/index.spec.ts +0 -321
  292. package/src/checks/valid-settings-key/index.ts +0 -144
  293. package/src/checks/valid-static-block-type/index.spec.ts +0 -38
  294. package/src/checks/valid-static-block-type/index.ts +0 -58
  295. package/src/checks/valid-visible-if/index.spec.ts +0 -619
  296. package/src/checks/valid-visible-if/index.ts +0 -184
  297. package/src/checks/valid-visible-if/visible-if-utils.ts +0 -158
  298. package/src/tags/content-for.ts +0 -25
  299. package/src/to-schema.ts +0 -231
  300. package/src/types/schemas/section.ts +0 -86
  301. package/src/types/schemas/theme-block.ts +0 -34
  302. package/src/types/theme-schemas.ts +0 -80
  303. package/src/utils/block.ts +0 -300
  304. package/src/utils/markup.ts +0 -10
@@ -1,72 +0,0 @@
1
- import {
2
- LiquidTag,
3
- LiquidTagAssign,
4
- LiquidTagCapture,
5
- LiquidTagEcho,
6
- NodeTypes,
7
- Position,
8
- } from '@platformos/liquid-html-parser';
9
- import { LiquidCheckDefinition, Severity, SourceCodeType } from '../../types';
10
- import { isNodeOfType } from '../utils';
11
-
12
- function isLiquidTagAssign(node: LiquidTag): node is LiquidTagAssign {
13
- return node.name === 'assign' && typeof node.markup !== 'string';
14
- }
15
- function isLiquidTagCapture(node: LiquidTag): node is LiquidTagCapture {
16
- return node.name === 'capture' && typeof node.markup !== 'string';
17
- }
18
- function isLiquidTagEcho(node: LiquidTag): node is LiquidTagEcho {
19
- return node.name === 'echo' && typeof node.markup !== 'string';
20
- }
21
-
22
- export const ContentForHeaderModification: LiquidCheckDefinition = {
23
- meta: {
24
- code: 'ContentForHeaderModification',
25
- name: 'Do not depend on the content of content_for_header',
26
- docs: {
27
- description:
28
- 'Do not rely on the content of content_for_header as it might change in the future, which could cause your Liquid code behavior to change.',
29
- url: 'https://shopify.dev/docs/storefronts/themes/tools/theme-check/checks/content-for-header-modification',
30
- recommended: true,
31
- },
32
- type: SourceCodeType.LiquidHtml,
33
- severity: Severity.ERROR,
34
- schema: {},
35
- targets: [],
36
- },
37
-
38
- create(context) {
39
- function checkContentForHeader(node: any, position: Position) {
40
- if (isNodeOfType(NodeTypes.VariableLookup, node) && node.name === 'content_for_header') {
41
- context.report({
42
- message: 'Do not rely on the content of `content_for_header`',
43
- startIndex: position.start,
44
- endIndex: position.end,
45
- });
46
- }
47
- }
48
-
49
- return {
50
- async LiquidTag(node) {
51
- if (isLiquidTagAssign(node)) {
52
- checkContentForHeader(node.markup.value.expression, node.position);
53
- } else if (isLiquidTagEcho(node)) {
54
- checkContentForHeader(node.markup.expression, node.position);
55
- } else if (isLiquidTagCapture(node) && node.children) {
56
- for (const child of node.children) {
57
- if (child.type === NodeTypes.LiquidVariableOutput && typeof child.markup !== 'string') {
58
- checkContentForHeader(child.markup.expression, child.position);
59
- }
60
- }
61
- }
62
- },
63
- async LiquidVariableOutput(node) {
64
- if (typeof node.markup === 'string') return;
65
-
66
- if (node.markup.filters.length) {
67
- checkContentForHeader(node.markup.expression, node.position);
68
- }
69
- },
70
- };
71
- },
72
- };
@@ -1,41 +0,0 @@
1
- import { expect, describe, it } from 'vitest';
2
- import { DeprecateBgsizes } from './index';
3
- import { runLiquidCheck, highlightedOffenses } from '../../test';
4
-
5
- describe('Module: DeprecateBgsizes', () => {
6
- it('should report offenses for deprecated attributes', async () => {
7
- const sourceCode = `
8
- <div class="lazyload" data-bgset="image.jpg"></div>
9
- <div class="lazyload" data-bgset="image2.jpg"></div>
10
- `;
11
-
12
- const offenses = await runLiquidCheck(DeprecateBgsizes, sourceCode);
13
- expect(offenses).to.have.length(4);
14
-
15
- const errorMessages = offenses.map((offense) => offense.message);
16
- expect(errorMessages).to.deep.equal([
17
- 'Use the native loading="lazy" attribute instead of lazysizes',
18
- 'Use the CSS imageset attribute instead of data-bgset',
19
- 'Use the native loading="lazy" attribute instead of lazysizes',
20
- 'Use the CSS imageset attribute instead of data-bgset',
21
- ]);
22
-
23
- const highlights = highlightedOffenses({ 'file.liquid': sourceCode }, offenses);
24
- expect(highlights).to.deep.equal([
25
- 'lazyload',
26
- 'data-bgset="image.jpg"',
27
- 'lazyload',
28
- 'data-bgset="image2.jpg"',
29
- ]);
30
- });
31
-
32
- it('should not report offenses for non-deprecated attributes', async () => {
33
- const sourceCode = `
34
- <div class="non-lazyload" data-non-bgset="image.jpg"></div>
35
- <div class="non-lazyload" data-non-bgset="image2.jpg"></div>
36
- `;
37
-
38
- const offenses = await runLiquidCheck(DeprecateBgsizes, sourceCode);
39
- expect(offenses).to.have.length(0);
40
- });
41
- });
@@ -1,49 +0,0 @@
1
- import { Severity, SourceCodeType, LiquidCheckDefinition } from '../../types';
2
- import { isAttr, isValuedHtmlAttribute, ValuedHtmlAttribute, valueIncludes } from '../utils';
3
-
4
- export const DeprecateBgsizes: LiquidCheckDefinition = {
5
- meta: {
6
- code: 'DeprecateBgsizes',
7
- name: 'Deprecate Bgsizes',
8
- docs: {
9
- description: 'This check is aimed at discouraging the use of the lazySizes bgset plugin.',
10
- recommended: true,
11
- url: 'https://shopify.dev/docs/storefronts/themes/tools/theme-check/checks/deprecate-bgsizes',
12
- },
13
- type: SourceCodeType.LiquidHtml,
14
- severity: Severity.WARNING,
15
- schema: {},
16
- targets: [],
17
- },
18
-
19
- create(context) {
20
- return {
21
- async HtmlElement(node) {
22
- const classAttributeWithLazyload: ValuedHtmlAttribute | undefined = node.attributes
23
- .filter(isValuedHtmlAttribute)
24
- .find((attr) => isAttr(attr, 'class') && valueIncludes(attr, 'lazyload'));
25
-
26
- if (classAttributeWithLazyload) {
27
- const attr = classAttributeWithLazyload;
28
- context.report({
29
- message: 'Use the native loading="lazy" attribute instead of lazysizes',
30
- startIndex: attr.attributePosition.start,
31
- endIndex: attr.attributePosition.end,
32
- });
33
- }
34
-
35
- const dataBgsetAttr = node.attributes.find(
36
- (attr) => isValuedHtmlAttribute(attr) && isAttr(attr, 'data-bgset'),
37
- ) as ValuedHtmlAttribute | undefined;
38
-
39
- if (dataBgsetAttr) {
40
- context.report({
41
- message: 'Use the CSS imageset attribute instead of data-bgset',
42
- startIndex: dataBgsetAttr.position.start,
43
- endIndex: dataBgsetAttr.position.end,
44
- });
45
- }
46
- },
47
- };
48
- },
49
- };
@@ -1,26 +0,0 @@
1
- import { expect, describe, it } from 'vitest';
2
- import { runLiquidCheck } from '../../test';
3
- import { DeprecateLazysizes } from './index';
4
-
5
- describe('Module: DeprecateLazysizes', () => {
6
- it('should report data-srcset and data-sizes attributes', async () => {
7
- const sourceCode = `
8
- <img data-srcset="image.jpg" data-sizes="auto" class="lazyload" />
9
- `;
10
-
11
- const offenses = await runLiquidCheck(DeprecateLazysizes, sourceCode);
12
- expect(offenses).to.have.length(1);
13
- expect(offenses[0].message).to.equal(
14
- 'Use the native loading="lazy" attribute instead of lazysizes',
15
- );
16
- });
17
-
18
- it('should not report srcset and sizes attributes', async () => {
19
- const sourceCode = `
20
- <img srcset="image.jpg" sizes="auto" loading="lazy" />
21
- `;
22
-
23
- const offenses = await runLiquidCheck(DeprecateLazysizes, sourceCode);
24
- expect(offenses).to.have.length(0);
25
- });
26
- });
@@ -1,58 +0,0 @@
1
- import { Severity, SourceCodeType, LiquidCheckDefinition } from '../../types';
2
- import {
3
- ValuedHtmlAttribute,
4
- isAttr,
5
- isValuedHtmlAttribute,
6
- isHtmlAttribute,
7
- valueIncludes,
8
- } from '../utils';
9
-
10
- function showsLazysizesUsage(attr: ValuedHtmlAttribute) {
11
- return isAttr(attr, 'data-srcset') || isAttr(attr, 'data-sizes');
12
- }
13
-
14
- export const DeprecateLazysizes: LiquidCheckDefinition = {
15
- meta: {
16
- code: 'DeprecateLazysizes',
17
- name: 'Deprecate Lazysizes',
18
- docs: {
19
- description:
20
- 'This check is aimed at discouraging the use of the lazysizes JavaScript library',
21
- recommended: true,
22
- url: 'https://shopify.dev/docs/storefronts/themes/tools/theme-check/checks/deprecate-lazysizes',
23
- },
24
- type: SourceCodeType.LiquidHtml,
25
- severity: Severity.WARNING,
26
- schema: {},
27
- targets: [],
28
- },
29
-
30
- create(context) {
31
- return {
32
- async HtmlVoidElement(node) {
33
- if (node.name !== 'img') return;
34
-
35
- const attributes = node.attributes.filter(isHtmlAttribute);
36
- const hasSrc = attributes.some((attr) => isAttr(attr, 'src'));
37
- const hasNativeLoading = attributes.some((attr) => isAttr(attr, 'loading'));
38
- if (hasSrc && hasNativeLoading) return;
39
-
40
- const hasLazyloadClass = node.attributes
41
- .filter(isValuedHtmlAttribute)
42
- .some((attr) => isAttr(attr, 'class') && valueIncludes(attr, 'lazyload'));
43
- if (!hasLazyloadClass) return;
44
-
45
- const hasLazysizesAttribute = node.attributes
46
- .filter(isValuedHtmlAttribute)
47
- .some(showsLazysizesUsage);
48
- if (!hasLazysizesAttribute) return;
49
-
50
- context.report({
51
- message: 'Use the native loading="lazy" attribute instead of lazysizes',
52
- startIndex: node.position.start,
53
- endIndex: node.position.end,
54
- });
55
- },
56
- };
57
- },
58
- };
@@ -1,264 +0,0 @@
1
- import {
2
- LiquidArgument,
3
- LiquidExpression,
4
- LiquidFilter,
5
- LiquidNamedArgument,
6
- LiquidNumber,
7
- LiquidString,
8
- LiquidVariableLookup,
9
- NodeTypes,
10
- } from '@platformos/liquid-html-parser';
11
- import { Fixer, LiquidHtmlSuggestion, SourceCodeType } from '../../types';
12
- import { isNodeOfType } from '../utils';
13
-
14
- type ImageSize = { width: number; height: number };
15
-
16
- type Suggestion = LiquidHtmlSuggestion[] | undefined;
17
-
18
- type FitlerParameters = Record<string, number | string | null>;
19
-
20
- /**
21
- * Width and height values cannot exceed this maximum size.
22
- */
23
- const MAX_SIZE = 5760;
24
-
25
- const NAMED_SIZES: Record<string, number> = {
26
- pico: 16,
27
- icon: 32,
28
- thumb: 50,
29
- small: 100,
30
- compact: 160,
31
- medium: 240,
32
- large: 480,
33
- grande: 600,
34
- original: 1024,
35
- };
36
-
37
- export function fixHexToRgba(node: LiquidFilter): Fixer<SourceCodeType.LiquidHtml> | undefined {
38
- /**
39
- * Cannot fix invalid usage.
40
- *
41
- * The `hex_to_rgba` filter is only valid with zero or one argument (`alpha`).
42
- */
43
- if (node.args.length > 1) return;
44
-
45
- const { start, end } = getFilterSourceStartAndEnd(node);
46
- const alpha = getExpressionArgumentValue(node, 0);
47
-
48
- let fixedFilter: string;
49
-
50
- if (alpha) {
51
- fixedFilter = ` color_to_rgb | color_modify: 'alpha', ${alpha}`;
52
- } else {
53
- fixedFilter = ' color_to_rgb';
54
- }
55
-
56
- return (corrector) => corrector.replace(start, end, fixedFilter);
57
- }
58
-
59
- export function suggestImgTagFix(node: LiquidFilter): Suggestion {
60
- const message = "Replace 'img_tag' with 'image_tag'.";
61
-
62
- const alt = getExpressionArgumentValue(node, 0);
63
- const cssClass = getExpressionArgumentValue(node, 1);
64
- const sizeStr = getExpressionArgumentValue(node, 2);
65
-
66
- const { width, height } = getImageSize(sizeStr, { width: -1, height: -1 });
67
- const { start, end } = getFilterSourceStartAndEnd(node);
68
-
69
- const imageUrlParameters: FitlerParameters = ensureImageValue({ width, height });
70
- const imageTagParameters: FitlerParameters = {
71
- width,
72
- height,
73
- alt: strValue(alt),
74
- class: strValue(cssClass),
75
- };
76
-
77
- const imageUrlFilter = buildFilterString('image_url', imageUrlParameters);
78
- const imageTagFilter = buildFilterString('image_tag', imageTagParameters);
79
-
80
- return [
81
- {
82
- message,
83
- fix: (corrector) => {
84
- const insert = `${imageUrlFilter} |${imageTagFilter}`;
85
- corrector.replace(start, end, insert);
86
- },
87
- },
88
- ];
89
- }
90
-
91
- export function suggestImgUrlFix(node: LiquidFilter): Suggestion {
92
- const message = "Replace 'img_url' with 'image_url'.";
93
-
94
- const cropNode = getNamedArgumentNode(node, 'crop');
95
- const formatNode = getNamedArgumentNode(node, 'format');
96
- const scaleNode = getNamedArgumentNode(node, 'scale');
97
- const sizeStr = getExpressionArgumentValue(node, 0);
98
- const sizeNode = node.args.at(0);
99
-
100
- /**
101
- * Cannot fix when 'scale' or 'size' node are variable lookups.
102
- */
103
- if (isVariableLookup(scaleNode?.value) || isVariableLookup(sizeNode)) {
104
- return;
105
- }
106
-
107
- const { width, height } = ensureImageValue(scaleImage(node, getImageSize(sizeStr)));
108
- const { start, end } = getFilterSourceStartAndEnd(node);
109
-
110
- const parameters: FitlerParameters = { width, height };
111
-
112
- if (isStringLiteral(cropNode?.value)) {
113
- parameters['crop'] = strValue(cropNode!.value.value);
114
- }
115
- if (isStringLiteral(formatNode?.value)) {
116
- parameters['format'] = strValue(formatNode!.value.value);
117
- }
118
- if (isVariableLookup(formatNode?.value)) {
119
- parameters['format'] = formatNode!.value.name;
120
- }
121
-
122
- return [
123
- {
124
- message,
125
- fix: (corrector) => {
126
- const insert = buildFilterString('image_url', parameters);
127
- corrector.replace(start, end, insert);
128
- },
129
- },
130
- ];
131
- }
132
-
133
- export function suggestImageUrlFix(filter: string, node: LiquidFilter): Suggestion {
134
- const message = `Replace '${filter}' with 'image_url'.`;
135
- const sizeStr = getExpressionArgumentValue(node, 0);
136
-
137
- const { width, height } = ensureImageValue(getImageSize(sizeStr));
138
- const { start, end } = getFilterSourceStartAndEnd(node);
139
-
140
- return [
141
- {
142
- message,
143
- fix: (corrector) => {
144
- const insert = buildFilterString('image_url', { width, height });
145
- corrector.replace(start, end, insert);
146
- },
147
- },
148
- ];
149
- }
150
-
151
- function getImageSize(size?: string, imageSize = { width: 100, height: 100 }): ImageSize {
152
- if (!size) return { ...imageSize };
153
-
154
- if (size in NAMED_SIZES) {
155
- const s = NAMED_SIZES[size];
156
- return { width: s, height: s };
157
- }
158
-
159
- const [width, height] = size.split('x').map((s) => parseInt(s));
160
-
161
- return ensureImageSizeLimit({ width, height });
162
- }
163
-
164
- function scaleImage(node: LiquidFilter, imageSize: ImageSize): ImageSize {
165
- const scale = parseInt(getNamedArgumentValue(node, 'scale') || '0') || 1;
166
-
167
- return ensureImageSizeLimit({
168
- width: imageSize.width * scale,
169
- height: imageSize.height * scale,
170
- });
171
- }
172
-
173
- function ensureImageSizeLimit(imageSize: ImageSize): ImageSize {
174
- return {
175
- width: Math.min(imageSize.width, MAX_SIZE),
176
- height: Math.min(imageSize.height, MAX_SIZE),
177
- };
178
- }
179
-
180
- function ensureImageValue(imageSize: ImageSize): ImageSize {
181
- let { width, height } = imageSize;
182
-
183
- const isImageSizeUnset = (!height || height === -1) && (!width || width === -1);
184
-
185
- /**
186
- * If `image_url` is missing a width or height, we default to width=100, as
187
- * the documentation mention an error is returned if neither are specified
188
- * (interestingly, `image_url` doesn't actually fail during runtime tests).
189
- *
190
- * That default value is widely mentioned in the documentation and we've
191
- * confirmed that in runtime tests.
192
- */
193
- if (isImageSizeUnset) {
194
- width = 100;
195
- }
196
-
197
- return { width, height };
198
- }
199
-
200
- function getExpressionArgumentValue(node: LiquidFilter, index: number): string | undefined {
201
- const arg = node.args.at(index);
202
-
203
- if (isNumberLiteral(arg) || isStringLiteral(arg)) {
204
- return arg.value;
205
- }
206
- }
207
-
208
- function getNamedArgumentValue(node: LiquidFilter, propertyName: string) {
209
- const argumentNode = getNamedArgumentNode(node, propertyName);
210
-
211
- const valueNode = argumentNode?.value;
212
-
213
- if (isNumberLiteral(valueNode) || isStringLiteral(valueNode)) {
214
- return valueNode.value;
215
- }
216
- }
217
-
218
- function getNamedArgumentNode(node: LiquidFilter, argName: string) {
219
- const args = node.args;
220
-
221
- return args.find(
222
- (arg): arg is LiquidNamedArgument =>
223
- isNodeOfType(NodeTypes.NamedArgument, arg) && arg.name === argName,
224
- );
225
- }
226
-
227
- function buildFilterString(filter: string, filterParameters: FitlerParameters) {
228
- const parameters = Object.entries(filterParameters)
229
- .filter(([_key, value]) => value && value !== -1)
230
- .map(([key, value]) => `${key}: ${value}`)
231
- .join(', ');
232
-
233
- if (!parameters) {
234
- return ` ${filter}`;
235
- }
236
-
237
- return ` ${filter}: ${parameters}`;
238
- }
239
-
240
- function getFilterSourceStartAndEnd(node: LiquidFilter) {
241
- const position = node.position;
242
- const pipePosition = node.source.slice(position.start).indexOf('|');
243
-
244
- return {
245
- start: position.start + pipePosition + 1,
246
- end: position.end,
247
- };
248
- }
249
-
250
- function strValue(value?: string) {
251
- return value ? `'${value}'` : null;
252
- }
253
-
254
- function isVariableLookup(exp?: LiquidExpression | LiquidArgument): exp is LiquidVariableLookup {
255
- return isNodeOfType(NodeTypes.VariableLookup, exp);
256
- }
257
-
258
- function isStringLiteral(exp?: LiquidExpression | LiquidArgument): exp is LiquidString {
259
- return isNodeOfType(NodeTypes.String, exp);
260
- }
261
-
262
- function isNumberLiteral(exp?: LiquidExpression | LiquidArgument): exp is LiquidNumber {
263
- return isNodeOfType(NodeTypes.Number, exp);
264
- }