@platformos/platformos-check-common 0.0.7 → 0.0.9

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 (337) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +4 -4
  3. package/dist/AugmentedPlatformOSDocset.d.ts +11 -0
  4. package/dist/AugmentedPlatformOSDocset.js +81 -0
  5. package/dist/AugmentedPlatformOSDocset.js.map +1 -0
  6. package/dist/JSONValidator.js +1 -1
  7. package/dist/JSONValidator.js.map +1 -1
  8. package/dist/checks/deprecated-filter/index.js +4 -41
  9. package/dist/checks/deprecated-filter/index.js.map +1 -1
  10. package/dist/checks/deprecated-tag/index.js +21 -22
  11. package/dist/checks/deprecated-tag/index.js.map +1 -1
  12. package/dist/checks/duplicate-function-arguments/index.js +1 -1
  13. package/dist/checks/duplicate-function-arguments/index.js.map +1 -1
  14. package/dist/checks/duplicate-render-partial-arguments/index.js +1 -1
  15. package/dist/checks/duplicate-render-partial-arguments/index.js.map +1 -1
  16. package/dist/checks/graphql/index.js +1 -1
  17. package/dist/checks/graphql/index.js.map +1 -1
  18. package/dist/checks/graphql-variables/index.js +4 -0
  19. package/dist/checks/graphql-variables/index.js.map +1 -1
  20. package/dist/checks/img-width-and-height/index.js +1 -1
  21. package/dist/checks/img-width-and-height/index.js.map +1 -1
  22. package/dist/checks/index.d.ts +3 -3
  23. package/dist/checks/index.js +4 -79
  24. package/dist/checks/index.js.map +1 -1
  25. package/dist/checks/json-syntax-error/index.js +1 -1
  26. package/dist/checks/json-syntax-error/index.js.map +1 -1
  27. package/dist/checks/liquid-html-syntax-error/checks/InvalidLoopArguments.js +1 -1
  28. package/dist/checks/liquid-html-syntax-error/checks/InvalidLoopArguments.js.map +1 -1
  29. package/dist/checks/liquid-html-syntax-error/checks/InvalidTagSyntax.d.ts +19 -0
  30. package/dist/checks/liquid-html-syntax-error/checks/InvalidTagSyntax.js +79 -0
  31. package/dist/checks/liquid-html-syntax-error/checks/InvalidTagSyntax.js.map +1 -0
  32. package/dist/checks/liquid-html-syntax-error/checks/UnknownTag.d.ts +3 -0
  33. package/dist/checks/liquid-html-syntax-error/checks/UnknownTag.js +32 -0
  34. package/dist/checks/liquid-html-syntax-error/checks/UnknownTag.js.map +1 -0
  35. package/dist/checks/liquid-html-syntax-error/index.js +23 -5
  36. package/dist/checks/liquid-html-syntax-error/index.js.map +1 -1
  37. package/dist/checks/matching-translations/index.d.ts +2 -2
  38. package/dist/checks/matching-translations/index.js +114 -90
  39. package/dist/checks/matching-translations/index.js.map +1 -1
  40. package/dist/checks/metadata-params/index.js +6 -3
  41. package/dist/checks/metadata-params/index.js.map +1 -1
  42. package/dist/checks/missing-asset/index.js +1 -1
  43. package/dist/checks/missing-asset/index.js.map +1 -1
  44. package/dist/checks/missing-partial/index.d.ts +6 -0
  45. package/dist/checks/missing-partial/index.js +70 -0
  46. package/dist/checks/missing-partial/index.js.map +1 -0
  47. package/dist/checks/orphaned-partial/index.js +4 -4
  48. package/dist/checks/orphaned-partial/index.js.map +1 -1
  49. package/dist/checks/parser-blocking-script/index.js +10 -36
  50. package/dist/checks/parser-blocking-script/index.js.map +1 -1
  51. package/dist/checks/parser-blocking-script/suggestions.d.ts +1 -2
  52. package/dist/checks/parser-blocking-script/suggestions.js +1 -11
  53. package/dist/checks/parser-blocking-script/suggestions.js.map +1 -1
  54. package/dist/checks/reserved-doc-param-names/index.js +6 -5
  55. package/dist/checks/reserved-doc-param-names/index.js.map +1 -1
  56. package/dist/checks/translation-key-exists/index.js +1 -1
  57. package/dist/checks/translation-key-exists/index.js.map +1 -1
  58. package/dist/checks/unclosed-html-element/index.js +5 -1
  59. package/dist/checks/unclosed-html-element/index.js.map +1 -1
  60. package/dist/checks/undefined-object/index.js +13 -31
  61. package/dist/checks/undefined-object/index.js.map +1 -1
  62. package/dist/checks/unique-doc-param-names/index.js +1 -1
  63. package/dist/checks/unique-doc-param-names/index.js.map +1 -1
  64. package/dist/checks/unknown-filter/index.js +3 -3
  65. package/dist/checks/unknown-filter/index.js.map +1 -1
  66. package/dist/checks/unknown-property/index.js +1 -1
  67. package/dist/checks/unknown-property/index.js.map +1 -1
  68. package/dist/checks/unrecognized-render-partial-arguments/index.js +2 -2
  69. package/dist/checks/unrecognized-render-partial-arguments/index.js.map +1 -1
  70. package/dist/checks/unused-assign/index.js +1 -1
  71. package/dist/checks/unused-assign/index.js.map +1 -1
  72. package/dist/checks/unused-doc-param/index.js +1 -1
  73. package/dist/checks/unused-doc-param/index.js.map +1 -1
  74. package/dist/checks/utils.js +1 -1
  75. package/dist/checks/utils.js.map +1 -1
  76. package/dist/checks/valid-content-for-arguments/index.js +1 -1
  77. package/dist/checks/valid-content-for-arguments/index.js.map +1 -1
  78. package/dist/checks/valid-doc-param-types/index.js +4 -4
  79. package/dist/checks/valid-doc-param-types/index.js.map +1 -1
  80. package/dist/checks/valid-html-translation/index.d.ts +2 -2
  81. package/dist/checks/valid-html-translation/index.js +4 -4
  82. package/dist/checks/valid-html-translation/index.js.map +1 -1
  83. package/dist/checks/valid-json/index.js +1 -1
  84. package/dist/checks/valid-json/index.js.map +1 -1
  85. package/dist/checks/valid-render-partial-argument-types/index.js +2 -2
  86. package/dist/checks/valid-render-partial-argument-types/index.js.map +1 -1
  87. package/dist/checks/variable-name/index.js +1 -1
  88. package/dist/checks/variable-name/index.js.map +1 -1
  89. package/dist/context-utils.d.ts +18 -7
  90. package/dist/context-utils.js +68 -109
  91. package/dist/context-utils.js.map +1 -1
  92. package/dist/disabled-checks/index.js +4 -2
  93. package/dist/disabled-checks/index.js.map +1 -1
  94. package/dist/doc-generator/DocBlockGenerator.d.ts +16 -0
  95. package/dist/doc-generator/DocBlockGenerator.js +464 -0
  96. package/dist/doc-generator/DocBlockGenerator.js.map +1 -0
  97. package/dist/doc-generator/index.d.ts +1 -0
  98. package/dist/doc-generator/index.js +6 -0
  99. package/dist/doc-generator/index.js.map +1 -0
  100. package/dist/find-root.d.ts +7 -10
  101. package/dist/find-root.js +10 -17
  102. package/dist/find-root.js.map +1 -1
  103. package/dist/fixes/autofix.d.ts +4 -4
  104. package/dist/fixes/autofix.js +2 -2
  105. package/dist/fixes/autofix.js.map +1 -1
  106. package/dist/fixes/correctors/index.js +4 -0
  107. package/dist/fixes/correctors/index.js.map +1 -1
  108. package/dist/index.d.ts +5 -5
  109. package/dist/index.js +50 -17
  110. package/dist/index.js.map +1 -1
  111. package/dist/jsonc/parse.d.ts +1 -1
  112. package/dist/jsonc/parse.js +1 -1
  113. package/dist/liquid-doc/arguments.d.ts +7 -8
  114. package/dist/liquid-doc/arguments.js +28 -29
  115. package/dist/liquid-doc/arguments.js.map +1 -1
  116. package/dist/liquid-doc/liquidDoc.d.ts +1 -1
  117. package/dist/liquid-doc/liquidDoc.js.map +1 -1
  118. package/dist/liquid-doc/utils.d.ts +3 -3
  119. package/dist/liquid-doc/utils.js +14 -3
  120. package/dist/liquid-doc/utils.js.map +1 -1
  121. package/dist/path.d.ts +1 -0
  122. package/dist/path.js +16 -1
  123. package/dist/path.js.map +1 -1
  124. package/{src/test/MockTheme.ts → dist/test/MockApp.d.ts} +2 -3
  125. package/dist/test/MockApp.js +16 -0
  126. package/dist/test/MockApp.js.map +1 -0
  127. package/dist/test/MockFileSystem.d.ts +3 -3
  128. package/dist/test/MockFileSystem.js +6 -6
  129. package/dist/test/MockFileSystem.js.map +1 -1
  130. package/dist/test/index.d.ts +1 -1
  131. package/dist/test/index.js +1 -1
  132. package/dist/test/index.js.map +1 -1
  133. package/dist/test/test-helper.d.ts +10 -9
  134. package/dist/test/test-helper.js +15 -106
  135. package/dist/test/test-helper.js.map +1 -1
  136. package/dist/to-schema.d.ts +1 -1
  137. package/dist/to-source-code.d.ts +3 -2
  138. package/dist/to-source-code.js +20 -0
  139. package/dist/to-source-code.js.map +1 -1
  140. package/dist/tsconfig.tsbuildinfo +1 -1
  141. package/dist/types/platformos-liquid-docs.d.ts +128 -0
  142. package/dist/types/platformos-liquid-docs.js +3 -0
  143. package/dist/types/platformos-liquid-docs.js.map +1 -0
  144. package/dist/types/schemas/index.d.ts +0 -2
  145. package/dist/types/schemas/index.js.map +1 -1
  146. package/dist/types.d.ts +26 -67
  147. package/dist/types.js +3 -5
  148. package/dist/types.js.map +1 -1
  149. package/dist/utils/block.js.map +1 -1
  150. package/dist/utils/index.d.ts +0 -1
  151. package/dist/utils/index.js +0 -1
  152. package/dist/utils/index.js.map +1 -1
  153. package/dist/yaml/parse.d.ts +5 -0
  154. package/dist/yaml/parse.js +94 -0
  155. package/dist/yaml/parse.js.map +1 -0
  156. package/package.json +4 -3
  157. package/src/{AugmentedThemeDocset.spec.ts → AugmentedPlatformOSDocset.spec.ts} +47 -34
  158. package/src/AugmentedPlatformOSDocset.ts +89 -0
  159. package/src/JSONValidator.ts +1 -1
  160. package/src/checks/deprecated-filter/index.spec.ts +76 -248
  161. package/src/checks/deprecated-filter/index.ts +5 -53
  162. package/src/checks/deprecated-tag/index.spec.ts +85 -34
  163. package/src/checks/deprecated-tag/index.ts +27 -22
  164. package/src/checks/duplicate-function-arguments/index.ts +1 -1
  165. package/src/checks/duplicate-render-partial-arguments/index.spec.ts +12 -12
  166. package/src/checks/duplicate-render-partial-arguments/index.ts +1 -1
  167. package/src/checks/graphql/index.ts +1 -1
  168. package/src/checks/graphql-variables/index.spec.ts +95 -0
  169. package/src/checks/graphql-variables/index.ts +4 -0
  170. package/src/checks/img-width-and-height/index.ts +2 -2
  171. package/src/checks/index.ts +11 -80
  172. package/src/checks/invalid-hash-assign-target/index.spec.ts +27 -27
  173. package/src/checks/json-syntax-error/index.ts +2 -2
  174. package/src/checks/liquid-html-syntax-error/checks/InvalidBooleanExpression.spec.ts +0 -11
  175. package/src/checks/liquid-html-syntax-error/checks/InvalidLoopArguments.spec.ts +1 -2
  176. package/src/checks/liquid-html-syntax-error/checks/InvalidLoopArguments.ts +2 -2
  177. package/src/checks/liquid-html-syntax-error/checks/InvalidTagSyntax.spec.ts +259 -0
  178. package/src/checks/liquid-html-syntax-error/checks/InvalidTagSyntax.ts +89 -0
  179. package/src/checks/liquid-html-syntax-error/checks/UnknownTag.spec.ts +293 -0
  180. package/src/checks/liquid-html-syntax-error/checks/UnknownTag.ts +43 -0
  181. package/src/checks/liquid-html-syntax-error/index.spec.ts +1 -6
  182. package/src/checks/liquid-html-syntax-error/index.ts +26 -5
  183. package/src/checks/matching-translations/index.spec.ts +187 -354
  184. package/src/checks/matching-translations/index.ts +117 -107
  185. package/src/checks/metadata-params/index.ts +6 -8
  186. package/src/checks/missing-asset/index.ts +1 -1
  187. package/src/checks/{missing-template → missing-partial}/index.spec.ts +6 -6
  188. package/src/checks/{missing-template → missing-partial}/index.ts +12 -26
  189. package/src/checks/orphaned-partial/index.ts +3 -3
  190. package/src/checks/parser-blocking-script/index.spec.ts +0 -118
  191. package/src/checks/parser-blocking-script/index.ts +3 -33
  192. package/src/checks/parser-blocking-script/suggestions.ts +1 -28
  193. package/src/checks/translation-key-exists/index.ts +1 -1
  194. package/src/checks/unclosed-html-element/index.ts +5 -1
  195. package/src/checks/undefined-object/index.spec.ts +32 -111
  196. package/src/checks/undefined-object/index.ts +15 -34
  197. package/src/checks/unique-doc-param-names/index.ts +1 -1
  198. package/src/checks/unknown-filter/index.spec.ts +2 -2
  199. package/src/checks/unknown-filter/index.ts +3 -3
  200. package/src/checks/unknown-property/index.ts +1 -1
  201. package/src/checks/unrecognized-render-partial-arguments/index.spec.ts +5 -5
  202. package/src/checks/unrecognized-render-partial-arguments/index.ts +2 -5
  203. package/src/checks/unused-assign/index.spec.ts +0 -30
  204. package/src/checks/unused-assign/index.ts +2 -2
  205. package/src/checks/unused-doc-param/index.ts +1 -1
  206. package/src/checks/utils.ts +1 -1
  207. package/src/checks/valid-doc-param-types/index.ts +4 -4
  208. package/src/checks/valid-html-translation/index.spec.ts +42 -32
  209. package/src/checks/valid-html-translation/index.ts +7 -7
  210. package/src/checks/valid-json/index.ts +2 -2
  211. package/src/checks/valid-render-partial-argument-types/index.spec.ts +13 -13
  212. package/src/checks/valid-render-partial-argument-types/index.ts +2 -5
  213. package/src/checks/variable-name/index.ts +1 -1
  214. package/src/context-utils.spec.ts +49 -77
  215. package/src/context-utils.ts +81 -129
  216. package/src/disabled-checks/index.spec.ts +26 -26
  217. package/src/disabled-checks/index.ts +2 -2
  218. package/src/disabled-checks/test-checks.ts +4 -4
  219. package/src/find-root.ts +12 -22
  220. package/src/fixes/autofix.spec.ts +2 -2
  221. package/src/fixes/autofix.ts +4 -4
  222. package/src/fixes/correctors/index.ts +4 -0
  223. package/src/ignore.spec.ts +4 -5
  224. package/src/index.ts +51 -21
  225. package/src/jsonc/parse.ts +1 -1
  226. package/src/liquid-doc/arguments.spec.ts +19 -45
  227. package/src/liquid-doc/arguments.ts +35 -42
  228. package/src/liquid-doc/liquidDoc.spec.ts +1 -1
  229. package/src/liquid-doc/liquidDoc.ts +1 -2
  230. package/src/liquid-doc/utils.ts +17 -8
  231. package/src/path.ts +16 -0
  232. package/src/test/MockApp.ts +17 -0
  233. package/src/test/MockFileSystem.spec.ts +10 -11
  234. package/src/test/MockFileSystem.ts +6 -6
  235. package/src/test/contain-offense.spec.ts +11 -3
  236. package/src/test/index.ts +1 -1
  237. package/src/test/test-helper.ts +43 -145
  238. package/src/to-source-code.ts +20 -1
  239. package/src/types/{theme-liquid-docs.ts → platformos-liquid-docs.ts} +8 -13
  240. package/src/types.ts +29 -92
  241. package/src/utils/index.ts +0 -1
  242. package/src/visitor.spec.ts +2 -2
  243. package/src/yaml/parse.ts +111 -0
  244. package/src/AugmentedThemeDocset.ts +0 -137
  245. package/src/checks/app-block-missing-schema/index.spec.ts +0 -121
  246. package/src/checks/app-block-missing-schema/index.ts +0 -46
  247. package/src/checks/app-block-valid-tags/index.spec.ts +0 -96
  248. package/src/checks/app-block-valid-tags/index.ts +0 -54
  249. package/src/checks/asset-preload/index.spec.ts +0 -78
  250. package/src/checks/asset-preload/index.ts +0 -65
  251. package/src/checks/asset-size-app-block-css/index.spec.ts +0 -88
  252. package/src/checks/asset-size-app-block-css/index.ts +0 -78
  253. package/src/checks/asset-size-app-block-javascript/index.spec.ts +0 -66
  254. package/src/checks/asset-size-app-block-javascript/index.ts +0 -78
  255. package/src/checks/asset-size-css/index.spec.ts +0 -166
  256. package/src/checks/asset-size-css/index.ts +0 -160
  257. package/src/checks/asset-size-javascript/index.spec.ts +0 -184
  258. package/src/checks/asset-size-javascript/index.ts +0 -144
  259. package/src/checks/block-id-usage/index.spec.ts +0 -76
  260. package/src/checks/block-id-usage/index.ts +0 -72
  261. package/src/checks/cdn-preconnect/index.spec.ts +0 -40
  262. package/src/checks/cdn-preconnect/index.ts +0 -43
  263. package/src/checks/content-for-header-modification/index.spec.ts +0 -65
  264. package/src/checks/content-for-header-modification/index.ts +0 -72
  265. package/src/checks/deprecate-bgsizes/index.spec.ts +0 -41
  266. package/src/checks/deprecate-bgsizes/index.ts +0 -49
  267. package/src/checks/deprecate-lazysizes/index.spec.ts +0 -26
  268. package/src/checks/deprecate-lazysizes/index.ts +0 -58
  269. package/src/checks/deprecated-filter/fixes.ts +0 -264
  270. package/src/checks/deprecated-fonts-on-sections-and-blocks/deprecated-fonts-data.ts +0 -1343
  271. package/src/checks/deprecated-fonts-on-sections-and-blocks/index.spec.ts +0 -613
  272. package/src/checks/deprecated-fonts-on-sections-and-blocks/index.ts +0 -284
  273. package/src/checks/deprecated-fonts-on-settings-schema/index.spec.ts +0 -102
  274. package/src/checks/deprecated-fonts-on-settings-schema/index.ts +0 -66
  275. package/src/checks/duplicate-content-for-arguments/index.spec.ts +0 -98
  276. package/src/checks/duplicate-content-for-arguments/index.ts +0 -43
  277. package/src/checks/empty-block-content/index.spec.ts +0 -117
  278. package/src/checks/empty-block-content/index.ts +0 -60
  279. package/src/checks/hardcoded-routes/index.spec.ts +0 -58
  280. package/src/checks/hardcoded-routes/index.ts +0 -100
  281. package/src/checks/json-missing-block/index.spec.ts +0 -435
  282. package/src/checks/json-missing-block/index.ts +0 -56
  283. package/src/checks/json-missing-block/missing-block-utils.ts +0 -147
  284. package/src/checks/liquid-free-settings/index.spec.ts +0 -180
  285. package/src/checks/liquid-free-settings/index.ts +0 -79
  286. package/src/checks/missing-content-for-arguments/index.spec.ts +0 -144
  287. package/src/checks/missing-content-for-arguments/index.ts +0 -46
  288. package/src/checks/pagination-size/index.spec.ts +0 -158
  289. package/src/checks/pagination-size/index.ts +0 -104
  290. package/src/checks/remote-asset/index.spec.ts +0 -280
  291. package/src/checks/remote-asset/index.ts +0 -238
  292. package/src/checks/reserved-doc-param-names/index.spec.ts +0 -62
  293. package/src/checks/reserved-doc-param-names/index.ts +0 -57
  294. package/src/checks/schema-presets-block-order/index.spec.ts +0 -344
  295. package/src/checks/schema-presets-block-order/index.ts +0 -154
  296. package/src/checks/schema-presets-static-blocks/index.spec.ts +0 -145
  297. package/src/checks/schema-presets-static-blocks/index.ts +0 -126
  298. package/src/checks/static-stylesheet-and-javascript-tags/index.spec.ts +0 -257
  299. package/src/checks/static-stylesheet-and-javascript-tags/index.ts +0 -48
  300. package/src/checks/unique-settings-id/index.spec.ts +0 -24
  301. package/src/checks/unique-settings-id/index.ts +0 -84
  302. package/src/checks/unique-settings-id/test-data.ts +0 -1191
  303. package/src/checks/unique-static-block-id/index.spec.ts +0 -55
  304. package/src/checks/unique-static-block-id/index.ts +0 -60
  305. package/src/checks/unrecognized-content-for-arguments/index.spec.ts +0 -145
  306. package/src/checks/unrecognized-content-for-arguments/index.ts +0 -55
  307. package/src/checks/valid-block-target/index.spec.ts +0 -1396
  308. package/src/checks/valid-block-target/index.ts +0 -142
  309. package/src/checks/valid-content-for-argument-types/index.spec.ts +0 -382
  310. package/src/checks/valid-content-for-argument-types/index.ts +0 -42
  311. package/src/checks/valid-content-for-arguments/index.spec.ts +0 -107
  312. package/src/checks/valid-content-for-arguments/index.ts +0 -98
  313. package/src/checks/valid-local-blocks/index.spec.ts +0 -286
  314. package/src/checks/valid-local-blocks/index.ts +0 -100
  315. package/src/checks/valid-local-blocks/valid-block-utils.ts +0 -97
  316. package/src/checks/valid-schema/index.spec.ts +0 -174
  317. package/src/checks/valid-schema/index.ts +0 -41
  318. package/src/checks/valid-schema-name/index.spec.ts +0 -112
  319. package/src/checks/valid-schema-name/index.ts +0 -75
  320. package/src/checks/valid-settings-key/index.spec.ts +0 -321
  321. package/src/checks/valid-settings-key/index.ts +0 -144
  322. package/src/checks/valid-static-block-type/index.spec.ts +0 -38
  323. package/src/checks/valid-static-block-type/index.ts +0 -58
  324. package/src/checks/valid-visible-if/index.spec.ts +0 -619
  325. package/src/checks/valid-visible-if/index.ts +0 -184
  326. package/src/checks/valid-visible-if/visible-if-utils.ts +0 -158
  327. package/src/tags/content-for.ts +0 -25
  328. package/src/to-schema.ts +0 -231
  329. package/src/types/schemas/index.ts +0 -5
  330. package/src/types/schemas/preset.ts +0 -52
  331. package/src/types/schemas/section.ts +0 -86
  332. package/src/types/schemas/setting.ts +0 -320
  333. package/src/types/schemas/template.ts +0 -34
  334. package/src/types/schemas/theme-block.ts +0 -34
  335. package/src/types/theme-schemas.ts +0 -80
  336. package/src/utils/block.ts +0 -300
  337. package/src/utils/markup.ts +0 -10
@@ -1,166 +0,0 @@
1
- import { vi, expect, describe, it, afterEach } from 'vitest';
2
- import { AssetSizeCSS } from '.';
3
- import { check, MockTheme } from '../../test';
4
- import { SchemaProp } from '../../types';
5
- import { hasRemoteAssetSizeExceededThreshold } from '../../utils/file-utils';
6
-
7
- vi.mock('../../utils/file-utils', async (importOriginal) => {
8
- const actual: any = await importOriginal();
9
- return {
10
- ...actual,
11
- hasRemoteAssetSizeExceededThreshold: vi.fn(),
12
- };
13
- });
14
-
15
- describe('Module: AssetSizeCSS', () => {
16
- const extensionFiles: MockTheme = {
17
- 'assets/theme.css': '* { color: green !important; }',
18
- 'templates/index.liquid': `
19
- <html>
20
- <head>
21
- <link href="{{ 'theme.css' | asset_url }}" rel="stylesheet">
22
- </head>
23
- </html>
24
- `,
25
- };
26
-
27
- const httpTest: MockTheme = {
28
- 'templates/index.liquid': `
29
- <html>
30
- <head>
31
- <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet">
32
- </head>
33
- </html>
34
- `,
35
- };
36
-
37
- afterEach(() => {
38
- vi.clearAllMocks();
39
- });
40
-
41
- it('should not report any offenses if CSS is smaller than threshold', async () => {
42
- const offenses = await check(extensionFiles, [AssetSizeCSS]);
43
-
44
- expect(offenses).toHaveLength(0);
45
- });
46
-
47
- it('should report an offense if CSS is larger than threshold', async () => {
48
- const offenses = await check(
49
- extensionFiles,
50
- [AssetSizeCSS],
51
- {},
52
- {
53
- AssetSizeCSS: {
54
- enabled: true,
55
- thresholdInBytes: 1,
56
- },
57
- },
58
- );
59
-
60
- expect(offenses).toHaveLength(1);
61
- expect(offenses[0]).toMatchObject({
62
- message: 'The CSS file size exceeds the threshold of 1 bytes',
63
- uri: 'file:///templates/index.liquid',
64
- start: { index: 51 },
65
- end: { index: 80 },
66
- });
67
- });
68
-
69
- it('should report a warning when the CSS file size exceeds the threshold', async () => {
70
- vi.mocked(hasRemoteAssetSizeExceededThreshold).mockReturnValue(Promise.resolve(true));
71
- const offenses = await check(
72
- httpTest,
73
- [AssetSizeCSS],
74
- {},
75
- {
76
- AssetSizeCSS: {
77
- enabled: true,
78
- thresholdInBytes: 1,
79
- },
80
- },
81
- );
82
-
83
- expect(offenses).toHaveLength(1);
84
- expect(offenses[0]).toMatchObject({
85
- message: 'The CSS file size exceeds the threshold of 1 bytes',
86
- uri: 'file:///templates/index.liquid',
87
- start: { index: 51 },
88
- end: { index: 122 },
89
- });
90
- });
91
-
92
- it('should not report any offenses if CSS is smaller than threshold 2', async () => {
93
- vi.mocked(hasRemoteAssetSizeExceededThreshold).mockResolvedValue(false);
94
- const extensionFiles: MockTheme = {
95
- 'assets/theme.css': 'console.log("hello world");',
96
- 'templates/index.liquid': `
97
- <html>
98
- <head>
99
- {{ 'theme.css' | asset_url | stylesheet_tag }}
100
- {{ "https://example.com" | stylesheet_tag }}
101
- </head>
102
- </html>
103
- `,
104
- };
105
-
106
- const offenses = await check(extensionFiles, [AssetSizeCSS]);
107
-
108
- expect(offenses).toHaveLength(0);
109
- });
110
-
111
- it('should report an offense if CSS is larger than threshold 2', async () => {
112
- vi.mocked(hasRemoteAssetSizeExceededThreshold).mockResolvedValue(true);
113
- const extensionFiles: MockTheme = {
114
- 'assets/theme.css': 'console.log("hello world");',
115
- 'templates/index.liquid': `
116
- <html>
117
- <head>
118
- {{ 'theme.css' | asset_url | stylesheet_tag }}
119
- {{ "https://example.com" | stylesheet_tag }}
120
- </head>
121
- </html>
122
- `,
123
- };
124
-
125
- const offenses = await check(
126
- extensionFiles,
127
- [AssetSizeCSS],
128
- {},
129
- {
130
- AssetSizeCSS: {
131
- enabled: true,
132
- thresholdInBytes: 2,
133
- },
134
- },
135
- );
136
-
137
- expect(offenses).toHaveLength(2);
138
- expect(offenses[0]).toMatchObject({
139
- message: 'The CSS file size exceeds the threshold of 2 bytes',
140
- uri: 'file:///templates/index.liquid',
141
- start: { index: 48 },
142
- end: { index: 89 },
143
- });
144
- expect(offenses[1]).toMatchObject({
145
- message: 'The CSS file size exceeds the threshold of 2 bytes',
146
- uri: 'file:///templates/index.liquid',
147
- start: { index: 107 },
148
- end: { index: 128 },
149
- });
150
- });
151
-
152
- it('should not report any offenses if there is no stylesheet', async () => {
153
- const extensionFiles: MockTheme = {
154
- 'templates/index.liquid': `
155
- <html>
156
- <head>
157
- </head>
158
- </html>
159
- `,
160
- };
161
-
162
- const offenses = await check(extensionFiles, [AssetSizeCSS]);
163
-
164
- expect(offenses).toHaveLength(0);
165
- });
166
- });
@@ -1,160 +0,0 @@
1
- import {
2
- LiquidHtmlNode,
3
- LiquidString,
4
- LiquidVariable,
5
- LiquidVariableOutput,
6
- NodeTypes,
7
- TextNode,
8
- } from '@platformos/liquid-html-parser';
9
- import { LiquidCheckDefinition, SchemaProp, Severity, SourceCodeType } from '../../types';
10
- import { last } from '../../utils';
11
- import {
12
- hasRemoteAssetSizeExceededThreshold,
13
- hasLocalAssetSizeExceededThreshold,
14
- } from '../../utils/file-utils';
15
- import {
16
- ValuedHtmlAttribute,
17
- isAttr,
18
- isNodeOfType,
19
- isValuedHtmlAttribute,
20
- valueIncludes,
21
- } from '../utils';
22
-
23
- const schema = {
24
- thresholdInBytes: SchemaProp.number(100000),
25
- };
26
-
27
- function isTextNode(node: LiquidHtmlNode): node is TextNode {
28
- return node.type === NodeTypes.TextNode;
29
- }
30
-
31
- function isLiquidVariableOutput(node: LiquidHtmlNode): node is LiquidVariableOutput {
32
- return node.type === NodeTypes.LiquidVariableOutput;
33
- }
34
-
35
- function isLiquidVariable(node: LiquidHtmlNode | string): node is LiquidVariable {
36
- return typeof node !== 'string' && node.type === NodeTypes.LiquidVariable;
37
- }
38
-
39
- function isString(node: LiquidHtmlNode): node is LiquidString {
40
- return node.type === NodeTypes.String;
41
- }
42
-
43
- export const AssetSizeCSS: LiquidCheckDefinition<typeof schema> = {
44
- meta: {
45
- code: 'AssetSizeCSS',
46
- aliases: ['AssetSizeCSSStylesheetTag'],
47
- name: 'Prevent Large CSS bundles',
48
- docs: {
49
- description: 'This check is aimed at preventing large CSS bundles for speed.',
50
- url: 'https://shopify.dev/docs/storefronts/themes/tools/theme-check/checks/asset-size-css',
51
- recommended: false,
52
- },
53
- type: SourceCodeType.LiquidHtml,
54
- severity: Severity.ERROR,
55
- schema,
56
- targets: [],
57
- },
58
-
59
- create(context) {
60
- if (!context.fileSize) {
61
- return {};
62
- }
63
-
64
- const thresholdInBytes = context.settings.thresholdInBytes;
65
-
66
- async function checkRemoteAssetSize(url: string, position: { start: number; end: number }) {
67
- if (await hasRemoteAssetSizeExceededThreshold(url, thresholdInBytes)) {
68
- context.report({
69
- message: `The CSS file size exceeds the threshold of ${thresholdInBytes} bytes`,
70
- startIndex: position.start,
71
- endIndex: position.end,
72
- });
73
- }
74
- }
75
-
76
- async function checkThemeAssetSize(srcValue: string, position: { start: number; end: number }) {
77
- if (
78
- await hasLocalAssetSizeExceededThreshold(context, `assets/${srcValue}`, thresholdInBytes)
79
- ) {
80
- context.report({
81
- message: `The CSS file size exceeds the threshold of ${thresholdInBytes} bytes`,
82
- startIndex: position.start,
83
- endIndex: position.end,
84
- });
85
- }
86
- }
87
-
88
- return {
89
- async HtmlVoidElement(node) {
90
- if (node.name !== 'link') return;
91
-
92
- const relIsStylesheet = node.attributes
93
- .filter(isValuedHtmlAttribute)
94
- .find((attr) => isAttr(attr, 'rel') && valueIncludes(attr, 'stylesheet'));
95
- if (!relIsStylesheet) return;
96
-
97
- const href: ValuedHtmlAttribute | undefined = node.attributes
98
- .filter(isValuedHtmlAttribute)
99
- .find((attr) => isAttr(attr, 'href'));
100
- if (!href) return;
101
- if (href.value.length !== 1) return;
102
-
103
- /* This ensures that the link entered is a text and not anything else like http//..{}
104
- This also checks if the value starts with 'http://', 'https://' or '//' to ensure its a valid link. */
105
- if (isTextNode(href.value[0]) && /(https?:)?\/\//.test(href.value[0].value)) {
106
- const url = href.value[0].value;
107
- await checkRemoteAssetSize(url, href.attributePosition);
108
- }
109
-
110
- /* This code checks if we have a link with a liquid variable
111
- and that its a string with one filter, `asset_url`. This is done to ensure our .css link is
112
- entered with a 'asset_url' to produce valid output. */
113
- if (
114
- isLiquidVariableOutput(href.value[0]) &&
115
- isLiquidVariable(href.value[0].markup) &&
116
- isString(href.value[0].markup.expression) &&
117
- href.value[0].markup.filters.length === 1 &&
118
- href.value[0].markup.filters[0].name === 'asset_url'
119
- ) {
120
- const assetName = href.value[0].markup.expression.value;
121
- await checkThemeAssetSize(assetName, href.attributePosition);
122
- }
123
- },
124
-
125
- async LiquidFilter(node, ancestors) {
126
- if (node.name !== 'stylesheet_tag') return;
127
-
128
- const liquidVariableParent = last(ancestors);
129
-
130
- if (!liquidVariableParent || !isNodeOfType(NodeTypes.LiquidVariable, liquidVariableParent))
131
- return;
132
-
133
- if (liquidVariableParent.expression.type !== NodeTypes.String) return;
134
-
135
- /* This code ensures we have a liquid variable with 1 expression, 1 filter, and that it is a valid http link.
136
- This is done to ensure a valid http link is entered with 1 filter being the `stylesheet_tag` for valid output. */
137
- if (
138
- liquidVariableParent.expression.value[0].length == 1 &&
139
- liquidVariableParent.filters.length == 1 &&
140
- /(https?:)?\/\//.test(liquidVariableParent.expression.value)
141
- ) {
142
- const url = liquidVariableParent.expression.value;
143
- await checkRemoteAssetSize(url, liquidVariableParent.expression.position);
144
- }
145
-
146
- /* This code ensures we have a liquid variable with 1 expression, 2 filters being asset_url and stylesheet_tag
147
- This is done to ensure a .css file has the 'asset_url' and 'stylesheet_tag' to produce the appropriate output. */
148
- if (
149
- liquidVariableParent.expression.value[0].length == 1 &&
150
- liquidVariableParent.filters.length == 2 &&
151
- liquidVariableParent.filters[0].name === 'asset_url' &&
152
- liquidVariableParent.filters[1].name === 'stylesheet_tag'
153
- ) {
154
- const css = liquidVariableParent.expression.value;
155
- await checkThemeAssetSize(css, liquidVariableParent.position);
156
- }
157
- },
158
- };
159
- },
160
- };
@@ -1,184 +0,0 @@
1
- import { expect, describe, it, afterEach, vi } from 'vitest';
2
- import { AssetSizeJavaScript } from '.';
3
- import { check, MockTheme } from '../../test';
4
- import { SchemaProp } from '../../types';
5
- import { hasRemoteAssetSizeExceededThreshold } from '../../utils/file-utils';
6
-
7
- vi.mock('../../utils/file-utils', async (importOriginal) => {
8
- const actual: any = await importOriginal();
9
- return {
10
- ...actual,
11
- hasRemoteAssetSizeExceededThreshold: vi.fn(),
12
- };
13
- });
14
-
15
- describe('Module: AssetSizeJavaScript', () => {
16
- const theme: MockTheme = {
17
- 'assets/theme.js': "console.log('hello world'); console.log('Oh. Hi Mark!')",
18
- 'templates/index.liquid': `
19
- <html>
20
- <head>
21
- <script src="{{ 'theme.js' | asset_url }}" defer></script>
22
- </head>
23
- </html>
24
- `,
25
- };
26
-
27
- const httpTest: MockTheme = {
28
- 'templates/index.liquid': `
29
- <html>
30
- <head>
31
- <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.min.js" defer></script>
32
- </head>
33
- </html>
34
- `,
35
- };
36
-
37
- afterEach(() => {
38
- vi.clearAllMocks();
39
- });
40
-
41
- it('should not find file size for invalid URLs', async () => {
42
- const invalidUrls = [
43
- 'https://{{ settings.url }}',
44
- "{{ 'this_file_does_not_exist.js' | asset_url }}",
45
- '{% if on_product %}https://hello.world{% else %}https://hi.world{% endif %}',
46
- ];
47
-
48
- for (const url of invalidUrls) {
49
- const offenses = await check(
50
- { 'templates/index.liquid': `<script src="${url}" defer></script>` },
51
- [AssetSizeJavaScript],
52
- );
53
- expect(offenses).toHaveLength(0);
54
- }
55
- });
56
-
57
- it('should report a warning when the JavaScript http request exceeds the threshold', async () => {
58
- vi.mocked(hasRemoteAssetSizeExceededThreshold).mockReturnValue(Promise.resolve(true));
59
- const offenses = await check(
60
- httpTest,
61
- [AssetSizeJavaScript],
62
- {},
63
- {
64
- AssetSizeJavaScript: {
65
- enabled: true,
66
- thresholdInBytes: 1,
67
- },
68
- },
69
- );
70
-
71
- expect(offenses).toHaveLength(1);
72
- expect(offenses[0]).toMatchObject({
73
- message:
74
- 'JavaScript on every page load exceeds compressed size threshold (1 Bytes), consider using the import on interaction pattern.',
75
- uri: 'file:///templates/index.liquid',
76
- start: { index: 52 },
77
- end: { index: 121 },
78
- });
79
- });
80
-
81
- it('should not report any offenses if JavaScript is smaller than threshold', async () => {
82
- const offenses = await check(theme, [AssetSizeJavaScript]);
83
-
84
- expect(offenses).toHaveLength(0);
85
- });
86
-
87
- it('should report an offense if JavaScript is larger than threshold', async () => {
88
- const offenses = await check(
89
- theme,
90
- [AssetSizeJavaScript],
91
- {},
92
- {
93
- AssetSizeJavaScript: {
94
- enabled: true,
95
- thresholdInBytes: 2,
96
- },
97
- },
98
- );
99
-
100
- expect(offenses).toHaveLength(1);
101
- expect(offenses[0]).toMatchObject({
102
- message:
103
- 'JavaScript on every page load exceeds compressed size threshold (2 Bytes), consider using the import on interaction pattern.',
104
- uri: 'file:///templates/index.liquid',
105
- start: { index: 52 },
106
- end: { index: 80 },
107
- });
108
- });
109
-
110
- it('should not report any offenses for inline JavaScript', async () => {
111
- const inlineTheme: MockTheme = {
112
- 'templates/index.liquid': `
113
- <html>
114
- <head>
115
- <script>
116
- console.log('hello world');
117
- </script>
118
- </head>
119
- </html>
120
- `,
121
- };
122
-
123
- const offenses = await check(inlineTheme, [AssetSizeJavaScript]);
124
-
125
- expect(offenses).toHaveLength(0);
126
- });
127
-
128
- it('should report an offense if JS is larger than threshold', async () => {
129
- const extensionFiles: MockTheme = {
130
- 'assets/theme.js': 'console.log("hello world");',
131
- 'templates/index.liquid': `
132
- <html>
133
- <head>
134
- {{ 'theme.js' | asset_url | script_tag }}
135
- {{ "https://example.com" | script_tag }}
136
- </head>
137
- </html>
138
- `,
139
- };
140
-
141
- const offenses = await check(
142
- extensionFiles,
143
- [AssetSizeJavaScript],
144
- {},
145
- {
146
- AssetSizeJavaScript: {
147
- enabled: true,
148
- thresholdInBytes: 2,
149
- },
150
- },
151
- );
152
-
153
- expect(offenses).toHaveLength(2);
154
- expect(offenses[0]).toMatchObject({
155
- message:
156
- 'JavaScript on every page load exceeds compressed size threshold (2 Bytes), consider using the import on interaction pattern.',
157
- uri: 'file:///templates/index.liquid',
158
- start: { index: 48 },
159
- end: { index: 84 },
160
- });
161
- expect(offenses[1]).toMatchObject({
162
- message:
163
- 'JavaScript on every page load exceeds compressed size threshold (2 Bytes), consider using the import on interaction pattern.',
164
- uri: 'file:///templates/index.liquid',
165
- start: { index: 102 },
166
- end: { index: 123 },
167
- });
168
- });
169
-
170
- it('should not report any offenses if there is no javascript', async () => {
171
- const extensionFiles: MockTheme = {
172
- 'templates/index.liquid': `
173
- <html>
174
- <head>
175
- </head>
176
- </html>
177
- `,
178
- };
179
-
180
- const offenses = await check(extensionFiles, [AssetSizeJavaScript]);
181
-
182
- expect(offenses).toHaveLength(0);
183
- });
184
- });
@@ -1,144 +0,0 @@
1
- import {
2
- LiquidString,
3
- LiquidVariable,
4
- LiquidVariableOutput,
5
- NodeTypes,
6
- TextNode,
7
- } from '@platformos/liquid-html-parser';
8
- import {
9
- LiquidCheckDefinition,
10
- LiquidHtmlNode,
11
- SchemaProp,
12
- Severity,
13
- SourceCodeType,
14
- } from '../../types';
15
- import { last } from '../../utils';
16
- import {
17
- hasRemoteAssetSizeExceededThreshold,
18
- hasLocalAssetSizeExceededThreshold,
19
- } from '../../utils/file-utils';
20
- import { ValuedHtmlAttribute, isAttr, isNodeOfType, isValuedHtmlAttribute } from '../utils';
21
-
22
- const schema = {
23
- thresholdInBytes: SchemaProp.number(10000),
24
- };
25
-
26
- function isTextNode(node: LiquidHtmlNode): node is TextNode {
27
- return node.type === NodeTypes.TextNode;
28
- }
29
-
30
- function isLiquidVariableOutput(node: LiquidHtmlNode): node is LiquidVariableOutput {
31
- return node.type === NodeTypes.LiquidVariableOutput;
32
- }
33
-
34
- function isLiquidVariable(node: LiquidHtmlNode | string): node is LiquidVariable {
35
- return typeof node !== 'string' && node.type === NodeTypes.LiquidVariable;
36
- }
37
-
38
- function isString(node: LiquidHtmlNode): node is LiquidString {
39
- return node.type === NodeTypes.String;
40
- }
41
-
42
- export const AssetSizeJavaScript: LiquidCheckDefinition<typeof schema> = {
43
- meta: {
44
- code: 'AssetSizeJavaScript',
45
- name: 'Prevent Large JavaScript bundles',
46
- docs: {
47
- description: 'This check is aimed at preventing large JavaScript bundles for speed.',
48
- url: 'https://shopify.dev/docs/storefronts/themes/tools/theme-check/checks/asset-size-javascript',
49
- recommended: false,
50
- },
51
- type: SourceCodeType.LiquidHtml,
52
- severity: Severity.ERROR,
53
- schema,
54
- targets: [],
55
- },
56
-
57
- create(context) {
58
- if (!context.fileSize) {
59
- return {};
60
- }
61
-
62
- const thresholdInBytes = context.settings.thresholdInBytes;
63
-
64
- async function checkRemoteAssetSize(url: string, position: { start: number; end: number }) {
65
- if (await hasRemoteAssetSizeExceededThreshold(url, thresholdInBytes)) {
66
- context.report({
67
- message: `JavaScript on every page load exceeds compressed size threshold (${thresholdInBytes} Bytes), consider using the import on interaction pattern.`,
68
- startIndex: position.start,
69
- endIndex: position.end,
70
- });
71
- }
72
- }
73
-
74
- async function checkThemeAssetSize(srcValue: string, position: { start: number; end: number }) {
75
- if (
76
- await hasLocalAssetSizeExceededThreshold(context, `assets/${srcValue}`, thresholdInBytes)
77
- ) {
78
- context.report({
79
- message: `JavaScript on every page load exceeds compressed size threshold (${thresholdInBytes} Bytes), consider using the import on interaction pattern.`,
80
- startIndex: position.start,
81
- endIndex: position.end,
82
- });
83
- }
84
- }
85
-
86
- return {
87
- async HtmlRawNode(node) {
88
- if (node.name !== 'script') return;
89
-
90
- const src: ValuedHtmlAttribute | undefined = node.attributes
91
- .filter(isValuedHtmlAttribute)
92
- .find((attr) => isAttr(attr, 'src'));
93
- if (!src) return;
94
- if (src.value.length !== 1) return;
95
-
96
- if (isTextNode(src.value[0]) && /(https?:)?\/\//.test(src.value[0].value)) {
97
- const url = src.value[0].value;
98
- await checkRemoteAssetSize(url, src.attributePosition);
99
- }
100
-
101
- if (
102
- isLiquidVariableOutput(src.value[0]) &&
103
- isLiquidVariable(src.value[0].markup) &&
104
- isString(src.value[0].markup.expression) &&
105
- src.value[0].markup.filters.length === 1 &&
106
- src.value[0].markup.filters[0].name === 'asset_url'
107
- ) {
108
- const assetName = src.value[0].markup.expression.value;
109
- await checkThemeAssetSize(assetName, src.attributePosition);
110
- }
111
- },
112
-
113
- async LiquidFilter(node, ancestors) {
114
- if (node.name !== 'script_tag') return;
115
-
116
- const liquidVariableParent = last(ancestors);
117
-
118
- if (!liquidVariableParent || !isNodeOfType(NodeTypes.LiquidVariable, liquidVariableParent))
119
- return;
120
-
121
- if (liquidVariableParent.expression.type !== NodeTypes.String) return;
122
-
123
- if (
124
- liquidVariableParent.expression.value[0].length == 1 &&
125
- liquidVariableParent.filters.length == 1 &&
126
- /(https?:)?\/\//.test(liquidVariableParent.expression.value)
127
- ) {
128
- const url = liquidVariableParent.expression.value;
129
- await checkRemoteAssetSize(url, liquidVariableParent.expression.position);
130
- }
131
-
132
- if (
133
- liquidVariableParent.expression.value[0].length == 1 &&
134
- liquidVariableParent.filters.length == 2 &&
135
- liquidVariableParent.filters[0].name === 'asset_url' &&
136
- liquidVariableParent.filters[1].name === 'script_tag'
137
- ) {
138
- const js = liquidVariableParent.expression.value;
139
- await checkThemeAssetSize(js, liquidVariableParent.position);
140
- }
141
- },
142
- };
143
- },
144
- };