@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,142 +0,0 @@
1
- import { nodeAtPath } from '../../json';
2
- import { getSchema } from '../../to-schema';
3
- import {
4
- LiquidCheckDefinition,
5
- LiteralNode,
6
- Section,
7
- Severity,
8
- SourceCodeType,
9
- ThemeBlock,
10
- } from '../../types';
11
- import {
12
- getBlocks,
13
- reportWarning,
14
- validateBlockFileExistence,
15
- validateNestedBlocks,
16
- isInvalidPresetBlock,
17
- isInvalidDefaultBlock,
18
- } from '../../utils';
19
-
20
- export const ValidBlockTarget: LiquidCheckDefinition = {
21
- meta: {
22
- code: 'ValidBlockTarget',
23
- name: 'Validate block targeting in presets',
24
- docs: {
25
- description:
26
- 'Ensures block types only reference valid block types and respect parent-child relationships',
27
- recommended: true,
28
- url: 'https://shopify.dev/docs/storefronts/themes/tools/theme-check/checks/valid-block-target',
29
- },
30
- type: SourceCodeType.LiquidHtml,
31
- severity: Severity.ERROR,
32
- schema: {},
33
- targets: [],
34
- },
35
-
36
- create(context) {
37
- return {
38
- async LiquidRawTag(node) {
39
- if (node.name !== 'schema' || node.body.kind !== 'json') return;
40
-
41
- const offset = node.blockStartPosition.end;
42
- const schema = await getSchema(context);
43
- const { validSchema, ast } = schema ?? {};
44
- if (!validSchema || validSchema instanceof Error) return;
45
- if (!ast || ast instanceof Error) return;
46
- if (!schema) return;
47
- const { staticBlockDefs } = schema;
48
-
49
- const {
50
- rootLevelThemeBlocks,
51
- rootLevelLocalBlocks,
52
- presetLevelBlocks,
53
- defaultLevelBlocks,
54
- } = getBlocks(validSchema);
55
-
56
- if (rootLevelLocalBlocks.length > 0) return;
57
-
58
- let errorsInRootLevelBlocks = false;
59
- await Promise.all(
60
- rootLevelThemeBlocks.map(async ({ node, path }) => {
61
- const typeNode = nodeAtPath(ast, path)! as LiteralNode;
62
- const exists = await validateBlockFileExistence(node.type, context);
63
- if (!exists) {
64
- errorsInRootLevelBlocks = true;
65
- reportWarning(blockDoesNotExistError(node.type), offset, typeNode, context);
66
- }
67
- }),
68
- );
69
-
70
- if (errorsInRootLevelBlocks) return;
71
-
72
- for (const [depthStr, blocks] of Object.entries(presetLevelBlocks)) {
73
- const depth = parseInt(depthStr, 10);
74
-
75
- if (depth === 0) {
76
- await Promise.all(
77
- blocks.map(async ({ node, path }) => {
78
- const typeNode = nodeAtPath(ast, path)! as LiteralNode;
79
- const blockId = 'id' in node ? node.id! : path.at(-2)!;
80
- const isStaticBlock = !!node.static;
81
-
82
- if (isInvalidPresetBlock(blockId, node, rootLevelThemeBlocks, staticBlockDefs)) {
83
- const errorMessage = isStaticBlock
84
- ? `Could not find a static block of type "${node.type}" with id "${blockId}" in this file.`
85
- : reportMissingThemeBlockDefinitionError(node);
86
- reportWarning(errorMessage, offset, typeNode, context);
87
- }
88
-
89
- const exists = await validateBlockFileExistence(node.type, context);
90
- if (exists) {
91
- if ('blocks' in node && node.blocks) {
92
- await validateNestedBlocks(
93
- context,
94
- node,
95
- node.blocks,
96
- path.slice(0, -1),
97
- offset,
98
- ast,
99
- );
100
- }
101
- } else {
102
- reportWarning(blockDoesNotExistError(node.type), offset, typeNode, context);
103
- }
104
- }),
105
- );
106
- }
107
- }
108
-
109
- await Promise.all(
110
- defaultLevelBlocks.map(async ({ node, path }) => {
111
- const typeNode = nodeAtPath(ast, path)! as LiteralNode;
112
-
113
- if (isInvalidDefaultBlock(node, rootLevelThemeBlocks)) {
114
- reportWarning(
115
- reportMissingThemeBlockDefinitionError(node),
116
- offset,
117
- typeNode,
118
- context,
119
- );
120
- }
121
-
122
- const exists = await validateBlockFileExistence(node.type, context);
123
- if (!exists) {
124
- reportWarning(blockDoesNotExistError(node.type), offset, typeNode, context);
125
- }
126
- }),
127
- );
128
- },
129
- };
130
- },
131
- };
132
-
133
- function reportMissingThemeBlockDefinitionError(node: Section.Block | ThemeBlock.Block) {
134
- const isPrivateBlockType = node.type.startsWith('_');
135
- return isPrivateBlockType
136
- ? `Theme block type "${node.type}" is a private block so it must be explicitly allowed in "blocks" at the root of this schema.`
137
- : `Theme block type "${node.type}" must be allowed in "blocks" at the root of this schema.`;
138
- }
139
-
140
- function blockDoesNotExistError(name: string) {
141
- return `Theme block 'blocks/${name}.liquid' does not exist.`;
142
- }
@@ -1,382 +0,0 @@
1
- import { describe, it, expect } from 'vitest';
2
- import { runLiquidCheck, applySuggestions } from '../../test';
3
- import { ValidContentForArgumentTypes } from '.';
4
- import { BasicParamTypes } from '../../liquid-doc/utils';
5
-
6
- describe('Module: ValidContentForParamTypes', () => {
7
- describe('type validation', () => {
8
- const typeTests = [
9
- {
10
- type: 'string',
11
- validValues: ["'hello'", "''", 'product'],
12
- invalidValues: [
13
- { value: '123', actualType: BasicParamTypes.Number },
14
- { value: 'true', actualType: BasicParamTypes.Boolean },
15
- ],
16
- },
17
- {
18
- type: 'number',
19
- validValues: ['0', '123', '-1', 'product'],
20
- invalidValues: [
21
- { value: "'hello'", actualType: BasicParamTypes.String },
22
- { value: 'true', actualType: BasicParamTypes.Boolean },
23
- ],
24
- },
25
- {
26
- type: 'boolean',
27
- validValues: ['true', 'false', 'nil', 'empty', 'product', '123', "'hello'"],
28
- invalidValues: [],
29
- },
30
- {
31
- type: 'object',
32
- validValues: ['product', '(1..3)'],
33
- invalidValues: [
34
- { value: "'hello'", actualType: BasicParamTypes.String },
35
- { value: '123', actualType: BasicParamTypes.Number },
36
- { value: 'true', actualType: BasicParamTypes.Boolean },
37
- { value: 'empty', actualType: BasicParamTypes.Boolean },
38
- ],
39
- },
40
- ];
41
-
42
- for (const test of typeTests) {
43
- describe(`${test.type} validation`, () => {
44
- const makeBlock = (type: string) => `
45
- {% doc %}
46
- @param {${type}} param - Description
47
- {% enddoc %}
48
- <div>{{ param }}</div>
49
- `;
50
-
51
- test.validValues.forEach((value) => {
52
- it(`should accept ${value} for ${test.type}`, async () => {
53
- const sourceCode = `{% content_for 'block', type: 'card', param: ${value} %}`;
54
- const offenses = await runLiquidCheck(
55
- ValidContentForArgumentTypes,
56
- sourceCode,
57
- undefined,
58
- {},
59
- {
60
- 'blocks/card.liquid': makeBlock(test.type),
61
- },
62
- );
63
- expect(offenses).toHaveLength(0);
64
- });
65
- });
66
-
67
- test.invalidValues.forEach(({ value, actualType: expectedType }) => {
68
- it(`should reject ${value} for ${test.type}`, async () => {
69
- const sourceCode = `{% content_for 'block', type: 'card', param: ${value} %}`;
70
- const offenses = await runLiquidCheck(
71
- ValidContentForArgumentTypes,
72
- sourceCode,
73
- undefined,
74
- {},
75
- {
76
- 'blocks/card.liquid': makeBlock(test.type),
77
- },
78
- );
79
- expect(offenses).toHaveLength(1);
80
- expect(offenses[0].message).toBe(
81
- `Type mismatch for argument 'param': expected ${test.type}, got ${expectedType}`,
82
- );
83
- });
84
- });
85
- });
86
- }
87
- });
88
-
89
- describe('edge cases', () => {
90
- it('should handle mixed case type annotations', async () => {
91
- const sourceCode = `{% content_for 'block', type: 'card', text: "hello", count: 5, flag: true, data: product %}`;
92
- const offenses = await runLiquidCheck(
93
- ValidContentForArgumentTypes,
94
- sourceCode,
95
- undefined,
96
- {},
97
- {
98
- 'blocks/card.liquid': `
99
- {% doc %}
100
- @param {String} text - The text
101
- @param {NUMBER} count - The count
102
- @param {BOOLEAN} flag - The flag
103
- @param {Object} data - The data
104
- {% enddoc %}
105
- <div>{{ text }}{{ count }}{{ flag }}{{ data }}</div>
106
- `,
107
- },
108
- );
109
- expect(offenses).toHaveLength(0);
110
- });
111
-
112
- it('should ignore variable lookups', async () => {
113
- const sourceCode = `{% content_for 'block', type: 'card', title: product_title %}`;
114
- const offenses = await runLiquidCheck(
115
- ValidContentForArgumentTypes,
116
- sourceCode,
117
- undefined,
118
- {},
119
- {
120
- 'blocks/card.liquid': `
121
- {% doc %}
122
- @param {String} title - The title
123
- {% enddoc %}
124
- <div>{{ title }}</div>
125
- `,
126
- },
127
- );
128
- expect(offenses).toHaveLength(0);
129
- });
130
-
131
- it('should not report when partial has no doc comment', async () => {
132
- const sourceCode = `{% content_for 'block', type: 'card', title: 123 %}`;
133
- const offenses = await runLiquidCheck(
134
- ValidContentForArgumentTypes,
135
- sourceCode,
136
- undefined,
137
- {},
138
- {
139
- 'blocks/card.liquid': `<h1>This partial has no doc comment</h1>`,
140
- },
141
- );
142
- expect(offenses).toHaveLength(0);
143
- });
144
-
145
- it('should not enforce unsupported types', async () => {
146
- const sourceCode = `{% content_for 'block', type: 'card', title: 123 %}`;
147
- const offenses = await runLiquidCheck(
148
- ValidContentForArgumentTypes,
149
- sourceCode,
150
- undefined,
151
- {},
152
- {
153
- 'blocks/card.liquid': `
154
- {% doc %}
155
- @param {Unsupported} title - The title
156
- {% enddoc %}
157
- <div>{{ title }}</div>
158
- `,
159
- },
160
- );
161
- expect(offenses).toHaveLength(0);
162
- });
163
-
164
- it('should not report for unrecognized arguments', async () => {
165
- const sourceCode = `{% content_for 'block', type: 'card', title: "hello", unrecognized: 123 %}`;
166
- const offenses = await runLiquidCheck(
167
- ValidContentForArgumentTypes,
168
- sourceCode,
169
- undefined,
170
- {},
171
- {
172
- 'blocks/card.liquid': `
173
- {% doc %}
174
- @param {String} title - The title
175
- {% enddoc %}
176
- <div>{{ title }}</div>
177
- `,
178
- },
179
- );
180
- expect(offenses).toHaveLength(0);
181
- });
182
- });
183
-
184
- describe('suggestions', () => {
185
- const makeBlock = (type: string) => `
186
- {% doc %}
187
- @param {${type}} param - Description
188
- {% enddoc %}
189
- <div>{{ param }}</div>
190
- `;
191
-
192
- it('should suggest replacing with default value for type or removing value', async () => {
193
- const sourceCode = `{% content_for 'block', type: 'card', param: 123 %}`;
194
- const offenses = await runLiquidCheck(
195
- ValidContentForArgumentTypes,
196
- sourceCode,
197
- undefined,
198
- {},
199
- {
200
- 'blocks/card.liquid': makeBlock('string'),
201
- },
202
- );
203
-
204
- expect(offenses).toHaveLength(1);
205
- expect(offenses[0].suggest).toHaveLength(2);
206
- expect(offenses[0].suggest?.[0]?.message).toBe("Replace with default value '''' for string");
207
-
208
- const result = applySuggestions(sourceCode, offenses[0]);
209
- expect(result?.[0]).toEqual(`{% content_for 'block', type: 'card', param: '' %}`);
210
-
211
- const suggestions = applySuggestions(sourceCode, offenses[0]);
212
- expect(suggestions?.[1]).toEqual(`{% content_for 'block', type: 'card', param: %}`);
213
- });
214
-
215
- it('should allow users to fix a single argument when multiple are provided`', async () => {
216
- const sourceCode = `{% content_for 'block', type: 'card', title: 123, count: 5 %}`;
217
- const offenses = await runLiquidCheck(
218
- ValidContentForArgumentTypes,
219
- sourceCode,
220
- undefined,
221
- {},
222
- {
223
- 'blocks/card.liquid': `
224
- {% doc %}
225
- @param {string} title - The title
226
- @param {number} count - The count
227
- {% enddoc %}
228
- <div>{{ title }} {{ count }}</div>
229
- `,
230
- },
231
- );
232
-
233
- expect(offenses).toHaveLength(1);
234
- expect(offenses[0].message).toBe(
235
- "Type mismatch for argument 'title': expected string, got number",
236
- );
237
-
238
- const result = applySuggestions(sourceCode, offenses[0]);
239
- expect(result?.[0]).toEqual(`{% content_for 'block', type: 'card', title: '', count: 5 %}`);
240
- });
241
-
242
- it('should handle arguments with trailing commas', async () => {
243
- const sourceCode = `{% content_for 'block', type: 'card', param: 123, %}`;
244
- const offenses = await runLiquidCheck(
245
- ValidContentForArgumentTypes,
246
- sourceCode,
247
- undefined,
248
- {},
249
- {
250
- 'blocks/card.liquid': makeBlock('string'),
251
- },
252
- );
253
-
254
- expect(offenses).toHaveLength(1);
255
-
256
- const result = applySuggestions(sourceCode, offenses[0]);
257
- expect(result?.[0]).toEqual(`{% content_for 'block', type: 'card', param: '', %}`);
258
- });
259
-
260
- it('should handle arguments with complex spacing', async () => {
261
- const sourceCode = `{% content_for 'block', type: 'card',
262
- title: 123,
263
- count: 5
264
- %}`;
265
- const offenses = await runLiquidCheck(
266
- ValidContentForArgumentTypes,
267
- sourceCode,
268
- undefined,
269
- {},
270
- {
271
- 'blocks/card.liquid': `
272
- {% doc %}
273
- @param {string} title - The title
274
- @param {number} count - The count
275
- {% enddoc %}
276
- `,
277
- },
278
- );
279
-
280
- expect(offenses).toHaveLength(1);
281
-
282
- const result = applySuggestions(sourceCode, offenses[0]);
283
- expect(result?.[0]).toEqual(`{% content_for 'block', type: 'card',
284
- title: '',
285
- count: 5
286
- %}`);
287
- });
288
-
289
- it('should handle argument with no space after colon', async () => {
290
- const sourceCode = `{% content_for 'block', type: 'card', param:123 %}`;
291
- const offenses = await runLiquidCheck(
292
- ValidContentForArgumentTypes,
293
- sourceCode,
294
- undefined,
295
- {},
296
- {
297
- 'blocks/card.liquid': makeBlock('string'),
298
- },
299
- );
300
-
301
- expect(offenses).toHaveLength(1);
302
-
303
- const result = applySuggestions(sourceCode, offenses[0]);
304
- expect(result?.[0]).toEqual(`{% content_for 'block', type: 'card', param:'' %}`);
305
- });
306
-
307
- it('should handle argument with multiple spaces after colon', async () => {
308
- const sourceCode = `{% content_for 'block', type: 'card', param: 123 %}`;
309
- const offenses = await runLiquidCheck(
310
- ValidContentForArgumentTypes,
311
- sourceCode,
312
- undefined,
313
- {},
314
- {
315
- 'blocks/card.liquid': makeBlock('string'),
316
- },
317
- );
318
-
319
- expect(offenses).toHaveLength(1);
320
-
321
- const result = applySuggestions(sourceCode, offenses[0]);
322
- expect(result?.[0]).toEqual(`{% content_for 'block', type: 'card', param: '' %}`);
323
- });
324
-
325
- it('should handle argument with newlines', async () => {
326
- const sourceCode = `{% content_for 'block', type: 'card', param:
327
- 123
328
- %}`;
329
- const offenses = await runLiquidCheck(
330
- ValidContentForArgumentTypes,
331
- sourceCode,
332
- undefined,
333
- {},
334
- {
335
- 'blocks/card.liquid': makeBlock('string'),
336
- },
337
- );
338
-
339
- expect(offenses).toHaveLength(1);
340
-
341
- const result = applySuggestions(sourceCode, offenses[0]);
342
- expect(result?.[0]).toEqual(`{% content_for 'block', type: 'card', param:
343
- ''
344
- %}`);
345
- });
346
-
347
- it('should suggest removal and replacement if expected type has a default value', async () => {
348
- const sourceCode = `{% content_for 'block', type: 'card', param: 123 %}`;
349
- const offenses = await runLiquidCheck(
350
- ValidContentForArgumentTypes,
351
- sourceCode,
352
- undefined,
353
- {},
354
- {
355
- 'blocks/card.liquid': makeBlock('string'),
356
- },
357
- );
358
-
359
- expect(offenses).toHaveLength(1);
360
- expect(offenses[0].suggest).toHaveLength(2);
361
- expect(offenses[0].suggest?.[0]?.message).toBe("Replace with default value '''' for string");
362
- expect(offenses[0].suggest?.[1]?.message).toBe('Remove value');
363
- });
364
-
365
- it("should only suggest removal if expected type default value is ''", async () => {
366
- const sourceCode = `{% content_for 'block', type: 'card', param: 123 %}`;
367
- const offenses = await runLiquidCheck(
368
- ValidContentForArgumentTypes,
369
- sourceCode,
370
- undefined,
371
- {},
372
- {
373
- 'blocks/card.liquid': makeBlock('object'),
374
- },
375
- );
376
-
377
- expect(offenses).toHaveLength(1);
378
- expect(offenses[0].suggest).toHaveLength(1);
379
- expect(offenses[0].suggest?.[0]?.message).toBe('Remove value');
380
- });
381
- });
382
- });
@@ -1,42 +0,0 @@
1
- import { LiquidCheckDefinition, Severity, SourceCodeType } from '../../types';
2
- import { ContentForMarkup } from '@platformos/liquid-html-parser';
3
- import {
4
- findTypeMismatchParams,
5
- getBlockName,
6
- getLiquidDocParams,
7
- reportTypeMismatches,
8
- } from '../../liquid-doc/arguments';
9
-
10
- export const ValidContentForArgumentTypes: LiquidCheckDefinition = {
11
- meta: {
12
- code: 'ValidContentForArgumentTypes',
13
- name: 'Valid ContentFor Argument Types',
14
- docs: {
15
- description:
16
- 'This check ensures that arguments passed to static blocks match the expected types defined in the liquidDoc header if present.',
17
- recommended: true,
18
- url: 'https://shopify.dev/docs/storefronts/themes/tools/theme-check/checks/valid-content-for-argument-types',
19
- },
20
- type: SourceCodeType.LiquidHtml,
21
- severity: Severity.WARNING,
22
- schema: {},
23
- targets: [],
24
- },
25
-
26
- create(context) {
27
- return {
28
- async ContentForMarkup(node: ContentForMarkup) {
29
- const blockName = getBlockName(node);
30
-
31
- if (!blockName) return;
32
-
33
- const liquidDocParameters = await getLiquidDocParams(context, `blocks/${blockName}.liquid`);
34
-
35
- if (!liquidDocParameters) return;
36
-
37
- const typeMismatchParams = findTypeMismatchParams(liquidDocParameters, node.args);
38
- reportTypeMismatches(context, typeMismatchParams, liquidDocParameters);
39
- },
40
- };
41
- },
42
- };
@@ -1,107 +0,0 @@
1
- import { describe, expect, it } from 'vitest';
2
- import { ValidContentForArguments } from '.';
3
- import { runLiquidCheck } from '../../test';
4
-
5
- describe('Module: ValidContentForArguments', () => {
6
- describe('{% content_for "unknown" %}', () => {
7
- it('should not report offenses for strategies we do not know or support yet', async () => {
8
- const offenses = await runLiquidCheck(
9
- ValidContentForArguments,
10
- '{% content_for "snippet", closest.product: product %}',
11
- );
12
- expect(offenses).toHaveLength(0);
13
- });
14
- });
15
-
16
- describe('{% content_for "blocks" %}', () => {
17
- it('should accept `closest.*` kwargs', async () => {
18
- const offenses = await runLiquidCheck(
19
- ValidContentForArguments,
20
- '{% content_for "blocks", closest.product: product %}',
21
- );
22
- expect(offenses).toHaveLength(0);
23
- });
24
-
25
- it('should not accept `context.*` kwargs', async () => {
26
- const offenses = await runLiquidCheck(
27
- ValidContentForArguments,
28
- '{% content_for "blocks", context.product: product %}',
29
- );
30
- expect(offenses).toHaveLength(1);
31
- expect(offenses[0]!.message).to.equal(
32
- `{% content_for "blocks" %} only accepts 'closest.*' arguments`,
33
- );
34
- });
35
-
36
- it('should report offenses for non-`closest.*` kwargs', async () => {
37
- const offenses = await runLiquidCheck(
38
- ValidContentForArguments,
39
- '{% content_for "blocks", product: product %}',
40
- );
41
- expect(offenses).toHaveLength(1);
42
- expect(offenses[0]!.message).to.equal(
43
- `{% content_for "blocks" %} only accepts 'closest.*' arguments`,
44
- );
45
- });
46
- });
47
-
48
- describe('{% content_for "block", type: "", id: "" %}', () => {
49
- it('should accept valid arguments', async () => {
50
- const offenses = await runLiquidCheck(
51
- ValidContentForArguments,
52
- '{% content_for "block", type: "text", id: "static-block" %}',
53
- );
54
- expect(offenses).toHaveLength(0);
55
- });
56
-
57
- it(`should report an offense if 'type' is not a string`, async () => {
58
- const offenses = await runLiquidCheck(
59
- ValidContentForArguments,
60
- '{% content_for "block", type: 10, id: "static-block" %}',
61
- );
62
- expect(offenses).toHaveLength(1);
63
- expect(offenses[0].message).to.equal(`The 'type' argument should be a string`);
64
- });
65
-
66
- it(`should report an offense if 'id' is not a string`, async () => {
67
- const offenses = await runLiquidCheck(
68
- ValidContentForArguments,
69
- '{% content_for "block", type: "foo", id: (0..10) %}',
70
- );
71
- expect(offenses).toHaveLength(1);
72
- expect(offenses[0].message).to.equal(`The 'id' argument should be a string`);
73
- });
74
-
75
- it(`should accept static arguments`, async () => {
76
- const offenses = await runLiquidCheck(
77
- ValidContentForArguments,
78
- '{% content_for "block", type: "foo", id: "id", product: product %}',
79
- );
80
- expect(offenses).toHaveLength(0);
81
- });
82
-
83
- it(`should report an offense for reserved arguments`, async () => {
84
- const offenses = await runLiquidCheck(
85
- ValidContentForArguments,
86
- '{% content_for "block", type: "foo", id: "id", settings: settings %}',
87
- );
88
- expect(offenses).toHaveLength(1);
89
- expect(offenses[0].message).to.equal(
90
- `{% content_for "block" %} doesn't support 'settings' because it's a reserved argument.`,
91
- );
92
- });
93
-
94
- it(`should report offenses for multiple reserved arguments`, async () => {
95
- const offenses = await runLiquidCheck(
96
- ValidContentForArguments,
97
- '{% content_for "block", type: "foo", id: "id", settings: settings, section: section %}',
98
- );
99
- const messages = offenses.map((o) => o.message);
100
-
101
- expect(messages).to.deep.equal([
102
- `{% content_for "block" %} doesn't support 'settings' because it's a reserved argument.`,
103
- `{% content_for "block" %} doesn't support 'section' because it's a reserved argument.`,
104
- ]);
105
- });
106
- });
107
- });