@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,174 +1,184 @@
1
1
  import {
2
- JSONCheckDefinition,
2
+ YAMLCheckDefinition,
3
3
  JSONNode,
4
- JSONSourceCode,
4
+ YAMLSourceCode,
5
5
  Severity,
6
6
  SourceCodeType,
7
7
  PropertyNode,
8
+ ObjectNode,
8
9
  } from '../../types';
9
10
 
10
11
  const PLURALIZATION_KEYS = new Set(['zero', 'one', 'two', 'few', 'many', 'other']);
11
12
 
12
- export const MatchingTranslations: JSONCheckDefinition = {
13
+ /**
14
+ * Returns the locale declared in a YAML translation file by reading its first
15
+ * top-level key (e.g. `en`, `pt-BR`, `fr`). platformOS determines a file's
16
+ * locale from content, not from its path.
17
+ */
18
+ function getLocaleFromAst(ast: JSONNode | Error): string | null {
19
+ if (ast instanceof Error) return null;
20
+ if (ast.type !== 'Object') return null;
21
+ const firstProp = (ast as ObjectNode).children[0];
22
+ if (!firstProp || firstProp.type !== 'Property') return null;
23
+ return firstProp.key.value || null;
24
+ }
25
+
26
+ /**
27
+ * Extracts the translations base directory from a relative file path.
28
+ *
29
+ * e.g. `app/translations/pt-BR.yml` → `app/translations`
30
+ * `app/translations/pt-BR/validation.yml` → `app/translations`
31
+ * `modules/x/public/translations/en.yml` → `modules/x/public/translations`
32
+ *
33
+ * Returns `null` if the path doesn't contain a `/translations/` segment.
34
+ */
35
+ function getTranslationRelativeBase(relativePath: string): string | null {
36
+ const idx = relativePath.lastIndexOf('/translations/');
37
+ if (idx === -1) return null;
38
+ return relativePath.substring(0, idx + '/translations'.length);
39
+ }
40
+
41
+ export const MatchingTranslations: YAMLCheckDefinition = {
13
42
  meta: {
14
43
  code: 'MatchingTranslations',
15
44
  name: 'Translation files should have the same keys',
16
45
  docs: {
17
46
  description: 'TODO',
18
47
  recommended: true,
19
- url: 'https://shopify.dev/docs/storefronts/themes/tools/theme-check/checks/matching-translations',
48
+ url: 'https://documentation.platformos.com/developer-guide/platformos-check/checks/matching-translations',
20
49
  },
21
- type: SourceCodeType.JSON,
50
+ type: SourceCodeType.YAML,
22
51
  severity: Severity.ERROR,
23
52
  schema: {},
24
53
  targets: [],
25
54
  },
26
55
 
27
56
  create(context) {
28
- // State
29
- const defaultTranslations = new Set<string>();
30
- const missingTranslations = new Set<string>();
57
+ // ── State ──────────────────────────────────────────────────────────────
58
+ const enTranslations = new Set<string>(); // keys present in the en scope
59
+ const missingFromLocale = new Set<string>(); // en keys absent from the entire locale scope
31
60
  const nodesByPath = new Map<string, PropertyNode>();
32
- const file = context.file;
61
+
62
+ const file = context.file as YAMLSourceCode;
33
63
  const fileUri = file.uri;
34
64
  const relativePath = context.toRelativePath(fileUri);
35
65
  const ast = file.ast;
36
- const isLocaleFile = relativePath.startsWith('locales/');
37
- const isDefaultTranslationsFile =
38
- fileUri.endsWith('.default.json') || fileUri.endsWith('.default.schema.json');
39
- const isSchemaTranslationFile = fileUri.endsWith('.schema.json');
40
-
41
- if (!isLocaleFile || isDefaultTranslationsFile || ast instanceof Error) {
42
- // No need to lint a file that isn't a translation file, we return an
43
- // empty object as the check for those.
66
+
67
+ // ── Guard: only lint translation files ────────────────────────────────
68
+ const isTranslationFile = relativePath.includes('/translations/');
69
+
70
+ // The locale is always the first top-level key in the YAML file (e.g. `en`,
71
+ // `pt-BR`). platformOS resolves locale from content, not from the file path.
72
+ const locale = getLocaleFromAst(ast);
73
+
74
+ if (!isTranslationFile || !locale || locale === 'en' || ast instanceof Error) {
44
75
  return {};
45
76
  }
46
77
 
47
- // Helpers
48
- const hasDefaultTranslations = () => defaultTranslations.size > 0;
49
- const isTerminalNode = ({ type }: JSONNode) => type === 'Literal';
50
- const isPluralizationNode = (node: PropertyNode) => PLURALIZATION_KEYS.has(node.key.value);
51
- const isShopifyPath = (path: string) => path.startsWith('shopify.');
78
+ // ── Derive scope (translation base URI) ──────────────────────────────
79
+ const relativeBase = getTranslationRelativeBase(relativePath);
80
+ if (!relativeBase) return {};
81
+
82
+ const translationBaseUri = context.toUri(relativeBase);
52
83
 
53
- const hasDefaultTranslation = (translationPath: string) =>
54
- defaultTranslations.has(translationPath) ?? false;
84
+ // A "primary" locale file is the top-level `{locale}.yml` (not inside a
85
+ // locale sub-directory like `pt-BR/`). Only the primary file reports
86
+ // missing translations to avoid duplicate offenses across split files.
87
+ const pathAfterBase = relativePath.substring(relativeBase.length + 1);
88
+ const isPrimaryLocaleFile = !pathAfterBase.includes('/');
55
89
 
90
+ // ── Helpers ───────────────────────────────────────────────────────────
91
+ const isTerminalNode = ({ type }: JSONNode) => type === 'Literal';
92
+ const isPluralizationNode = (node: PropertyNode) => PLURALIZATION_KEYS.has(node.key.value);
56
93
  const isPluralizationPath = (path: string) =>
57
94
  [...PLURALIZATION_KEYS].some((key) => path.endsWith(key));
58
95
 
59
- const jsonPaths = (json: any): string[] => {
60
- const keys = Object.keys(json);
96
+ const countCommonParts = (a: string[], b: string[]): number => {
97
+ const min = Math.min(a.length, b.length);
98
+ for (let i = 0; i < min; i++) if (a[i] !== b[i]) return i;
99
+ return min;
100
+ };
61
101
 
62
- return keys.reduce((acc: string[], key: string) => {
63
- if (typeof json[key] !== 'object') {
64
- return acc.concat(key);
102
+ const closestTranslationKey = (key: string) => {
103
+ const keyParts = key.split('.');
104
+ let closest = '';
105
+ let max = 0;
106
+ for (const path of nodesByPath.keys()) {
107
+ const common = countCommonParts(path.split('.'), keyParts);
108
+ if (common > max) {
109
+ max = common;
110
+ closest = path;
65
111
  }
66
-
67
- const childJson = json[key];
68
- const childPaths = jsonPaths(childJson);
69
-
70
- return acc.concat(childPaths.map((path) => `${key}.${path}`));
71
- }, []);
112
+ }
113
+ return nodesByPath.get(closest) ?? ast;
72
114
  };
73
115
 
116
+ // Strip the locale prefix (first Property in the ancestors chain).
117
+ // YAML files wrap content under a locale key: { en: { hello: 'Hello' } }
118
+ // We want paths like 'hello', not 'en.hello'.
74
119
  const objectPath = (nodes: JSONNode[]) => {
75
- return nodes
76
- .filter((node): node is PropertyNode => node.type === 'Property')
77
- .reduce((acc: string[], val) => acc.concat(val.key.value), [])
120
+ const props = nodes.filter((n): n is PropertyNode => n.type === 'Property');
121
+ if (props.length <= 1) return '';
122
+ return props
123
+ .slice(1)
124
+ .map((p) => p.key.value)
78
125
  .join('.');
79
126
  };
80
127
 
81
- const countCommonParts = (arrayA: string[], arrayB: string[]): number => {
82
- const minLength = Math.min(arrayA.length, arrayB.length);
83
-
84
- for (let i = 0; i < minLength; i++) {
85
- if (arrayA[i] !== arrayB[i]) {
86
- return i;
87
- }
88
- }
89
-
90
- return minLength;
91
- };
92
-
93
- const closestTranslationKey = (translationKey: string) => {
94
- const translationKeyParts = translationKey.split('.');
95
- let closestMatch = '';
96
- let maxCommonParts = 0;
97
-
98
- for (const path of nodesByPath.keys()) {
99
- const pathParts = path.split('.');
100
- const commonParts = countCommonParts(pathParts, translationKeyParts);
101
-
102
- if (commonParts > maxCommonParts) {
103
- maxCommonParts = commonParts;
104
- closestMatch = path;
105
- }
106
- }
107
-
108
- return nodesByPath.get(closestMatch) ?? ast;
109
- };
128
+ const jsonPaths = (json: any): string[] =>
129
+ Object.keys(json).reduce((acc: string[], key: string) => {
130
+ if (typeof json[key] !== 'object') return acc.concat(key);
131
+ return acc.concat(jsonPaths(json[key]).map((p) => `${key}.${p}`));
132
+ }, []);
110
133
 
111
134
  return {
112
135
  async onCodePathStart() {
113
- const getDefaultTranslations = isSchemaTranslationFile
114
- ? context.getDefaultSchemaTranslations
115
- : context.getDefaultTranslations;
116
- const defaultTranslationPaths = await getDefaultTranslations().then(jsonPaths);
117
- defaultTranslationPaths.forEach(Set.prototype.add, defaultTranslations);
118
-
119
- // At the `onCodePathStart`, we assume that all translations are missing,
120
- // and remove translation paths while traversing through the file.
121
- defaultTranslationPaths.forEach(Set.prototype.add, missingTranslations);
136
+ // Aggregate ALL en translations in this scope (en.yml + en/*.yml)
137
+ const en = await context.getTranslationsForBase(translationBaseUri, 'en');
138
+ jsonPaths(en).forEach(Set.prototype.add, enTranslations);
139
+
140
+ if (!isPrimaryLocaleFile) return;
141
+
142
+ // For the primary locale file: pre-compute which en keys are absent
143
+ // from the entire locale scope (locale.yml + locale/*.yml).
144
+ const localeAgg = await context.getTranslationsForBase(translationBaseUri, locale);
145
+ const localeKeys = new Set(jsonPaths(localeAgg));
146
+ for (const key of enTranslations) {
147
+ if (!localeKeys.has(key)) missingFromLocale.add(key);
148
+ }
122
149
  },
123
150
 
124
151
  async Property(node, ancestors) {
125
152
  const path = objectPath(ancestors.concat(node));
153
+ if (!path) return;
126
154
 
127
155
  nodesByPath.set(path, node);
128
156
 
129
- if (!hasDefaultTranslations()) return;
130
157
  if (isPluralizationNode(node)) return;
131
158
  if (!isTerminalNode(node.value)) return;
132
- if (isShopifyPath(path)) return;
159
+ if (!enTranslations.size) return; // no en reference — skip
133
160
 
134
- if (hasDefaultTranslation(path)) {
135
- // As `path` is present, we remove it from the
136
- // `missingTranslationsPerFile` bucket.
137
- missingTranslations.delete(path);
138
- return;
161
+ if (!enTranslations.has(path)) {
162
+ context.report({
163
+ message: `A translation for '${path}' does not exist in the en locale`,
164
+ startIndex: node.loc!.start.offset,
165
+ endIndex: node.loc!.end.offset,
166
+ });
139
167
  }
140
-
141
- context.report({
142
- message: `A default translation for '${path}' does not exist`,
143
- startIndex: node.loc!.start.offset,
144
- endIndex: node.loc!.end.offset,
145
- suggest: [
146
- {
147
- message: 'Delete unneeded translation key',
148
- fix(corrector) {
149
- corrector.remove(path);
150
- },
151
- },
152
- ],
153
- });
154
168
  },
155
169
 
156
170
  async onCodePathEnd() {
157
- missingTranslations.forEach((path) => {
158
- const closest = closestTranslationKey(path);
159
-
160
- if (isPluralizationPath(path)) return;
161
- if (isShopifyPath(path)) return;
171
+ if (!isPrimaryLocaleFile) return;
162
172
 
173
+ for (const key of missingFromLocale) {
174
+ if (isPluralizationPath(key)) continue;
175
+ const closest = closestTranslationKey(key);
163
176
  context.report({
164
- message: `The translation for '${path}' is missing`,
177
+ message: `The translation for '${key}' is missing`,
165
178
  startIndex: closest.loc!.start.offset,
166
179
  endIndex: closest.loc!.end.offset,
167
- fix(corrector) {
168
- corrector.add(path, 'TODO');
169
- },
170
180
  });
171
- });
181
+ }
172
182
  },
173
183
  };
174
184
  },
@@ -3,7 +3,6 @@ import yaml from 'js-yaml';
3
3
  import { DocumentsLocator, DocumentType } from '@platformos/platformos-common';
4
4
  import { URI } from 'vscode-uri';
5
5
  import { LiquidNamedArgument, Position } from '@platformos/liquid-html-parser';
6
- import { getLiquidDocParams } from '../../liquid-doc/arguments';
7
6
  import { relative } from '../../path';
8
7
 
9
8
  type Metadata = {
@@ -64,12 +63,11 @@ export const MetadataParamsCheck: LiquidCheckDefinition = {
64
63
  }
65
64
  let params = extractMetadataParams(await context.fs.readFile(locatedFile));
66
65
  if (!params) {
67
- const liquidDocParameters = await getLiquidDocParams(
68
- context,
69
- relative(locatedFile, context.config.rootUri),
70
- );
71
-
72
- if (!liquidDocParameters) return;
66
+ if (!context.getDocDefinition) return;
67
+ const relativePath = relative(locatedFile, context.config.rootUri);
68
+ const docDef = await context.getDocDefinition(relativePath);
69
+ if (!docDef?.liquidDoc?.parameters) return;
70
+ const liquidDocParameters = new Map(docDef.liquidDoc.parameters.map((p) => [p.name, p]));
73
71
 
74
72
  params = Array.from(liquidDocParameters.values())
75
73
  .filter((p) => p.required)
@@ -99,7 +97,7 @@ export const MetadataParamsCheck: LiquidCheckDefinition = {
99
97
 
100
98
  return {
101
99
  async RenderMarkup(node) {
102
- const targetFile = 'value' in node.snippet ? node.snippet.value : node.snippet.name;
100
+ const targetFile = 'value' in node.partial ? node.partial.value : node.partial.name;
103
101
  if (!targetFile) {
104
102
  return;
105
103
  }
@@ -11,7 +11,7 @@ export const MissingAsset: LiquidCheckDefinition = {
11
11
  docs: {
12
12
  description: 'Reports missing asset files',
13
13
  recommended: true,
14
- url: 'https://shopify.dev/docs/storefronts/themes/tools/theme-check/checks/missing-asset',
14
+ url: 'https://documentation.platformos.com/developer-guide/platformos-check/checks/missing-asset',
15
15
  },
16
16
  type: SourceCodeType.LiquidHtml,
17
17
  severity: Severity.ERROR,
@@ -1,9 +1,9 @@
1
1
  import { expect, describe, it } from 'vitest';
2
- import { MissingTemplate } from '.';
2
+ import { MissingPartial } from '.';
3
3
  import { check } from '../../test';
4
4
 
5
- describe('Module: MissingTemplate', () => {
6
- it('should report missing template errors', async () => {
5
+ describe('Module: MissingPartial', () => {
6
+ it('should report missing partial errors', async () => {
7
7
  const testCases = [
8
8
  {
9
9
  testCase: 'should report the missing partial to be rendered with "render"',
@@ -12,7 +12,7 @@ describe('Module: MissingTemplate', () => {
12
12
  {% render myvariable %}
13
13
  `,
14
14
  expected: {
15
- check: 'MissingTemplate',
15
+ check: 'MissingPartial',
16
16
  end: {
17
17
  character: 27,
18
18
  index: 28,
@@ -49,11 +49,11 @@ describe('Module: MissingTemplate', () => {
49
49
  },
50
50
  ];
51
51
  for (const { testCase, file, expected, filesWith } of testCases) {
52
- const offenses = await check(filesWith(file), [MissingTemplate]);
52
+ const offenses = await check(filesWith(file), [MissingPartial]);
53
53
 
54
54
  expect(offenses).to.have.length(1);
55
55
  expect(offenses, testCase).to.containOffense({
56
- check: MissingTemplate.meta.code,
56
+ check: MissingPartial.meta.code,
57
57
  ...expected,
58
58
  });
59
59
  }
@@ -1,19 +1,5 @@
1
- import {
2
- LiquidTag,
3
- LiquidTagNamed,
4
- NamedTags,
5
- NodeTypes,
6
- Position,
7
- } from '@platformos/liquid-html-parser';
8
- import { minimatch } from 'minimatch';
9
- import {
10
- LiquidCheckDefinition,
11
- RelativePath,
12
- SchemaProp,
13
- Severity,
14
- SourceCodeType,
15
- } from '../../types';
16
- import { doesFileExist } from '../../utils/file-utils';
1
+ import { NodeTypes } from '@platformos/liquid-html-parser';
2
+ import { LiquidCheckDefinition, SchemaProp, Severity, SourceCodeType } from '../../types';
17
3
  import { DocumentsLocator } from '@platformos/platformos-common';
18
4
  import { URI } from 'vscode-uri';
19
5
 
@@ -21,14 +7,14 @@ const schema = {
21
7
  ignoreMissing: SchemaProp.array(SchemaProp.string(), []),
22
8
  };
23
9
 
24
- export const MissingTemplate: LiquidCheckDefinition<typeof schema> = {
10
+ export const MissingPartial: LiquidCheckDefinition<typeof schema> = {
25
11
  meta: {
26
- code: 'MissingTemplate',
27
- name: 'Avoid rendering missing templates',
12
+ code: 'MissingPartial',
13
+ name: 'Avoid rendering missing partials',
28
14
  docs: {
29
15
  description: 'Reports missing partial liquid file',
30
16
  recommended: true,
31
- url: 'https://shopify.dev/docs/storefronts/themes/tools/theme-check/checks/missing-template',
17
+ url: 'https://documentation.platformos.com/developer-guide/platformos-check/checks/missing-partial',
32
18
  },
33
19
  type: SourceCodeType.LiquidHtml,
34
20
  severity: Severity.ERROR,
@@ -41,20 +27,20 @@ export const MissingTemplate: LiquidCheckDefinition<typeof schema> = {
41
27
 
42
28
  return {
43
29
  async RenderMarkup(node) {
44
- if (node.snippet.type === NodeTypes.VariableLookup) return;
30
+ if (node.partial.type === NodeTypes.VariableLookup) return;
45
31
 
46
- const snippet = node.snippet;
32
+ const partial = node.partial;
47
33
  const location = await locator.locate(
48
34
  URI.parse(context.config.rootUri),
49
35
  'render',
50
- snippet.value,
36
+ partial.value,
51
37
  );
52
38
 
53
39
  if (!location) {
54
40
  context.report({
55
- message: `'${snippet.value}' does not exist`,
56
- startIndex: node.snippet.position.start,
57
- endIndex: node.snippet.position.end,
41
+ message: `'${partial.value}' does not exist`,
42
+ startIndex: node.partial.position.start,
43
+ endIndex: node.partial.position.end,
58
44
  });
59
45
  }
60
46
  },
@@ -1,4 +1,4 @@
1
- import { isPartial } from '../../to-schema';
1
+ import { isPartial } from '../../path';
2
2
  import { LiquidCheckDefinition, Severity, SourceCodeType } from '../../types';
3
3
 
4
4
  export const OrphanedPartial: LiquidCheckDefinition = {
@@ -6,9 +6,9 @@ export const OrphanedPartial: LiquidCheckDefinition = {
6
6
  code: 'OrphanedPartial',
7
7
  name: 'Prevent orphaned partials',
8
8
  docs: {
9
- description: 'This check exists to prevent orphaned partials in themes.',
9
+ description: 'This check exists to prevent orphaned partials in platformOS apps.',
10
10
  recommended: true,
11
- url: 'https://shopify.dev/docs/storefronts/themes/tools/theme-check/checks/orphaned-partial',
11
+ url: 'https://documentation.platformos.com/developer-guide/platformos-check/checks/orphaned-partial',
12
12
  },
13
13
  type: SourceCodeType.LiquidHtml,
14
14
  severity: Severity.WARNING,
@@ -3,26 +3,6 @@ import { ParserBlockingScript } from '.';
3
3
  import { applySuggestions, check as reportOffenses } from '../../test';
4
4
 
5
5
  describe('Module: ParserBlockingScript', () => {
6
- it('should report the correct offense for the Liquid filter', async () => {
7
- const file = "{{ 'asset' | script_tag }}";
8
- const startIndex = file.indexOf('script_tag');
9
- const endIndex = startIndex + 'script_tag'.length;
10
-
11
- const offenses = await reportOffenses(
12
- {
13
- 'code.liquid': file,
14
- },
15
- [ParserBlockingScript],
16
- );
17
-
18
- expect(offenses).to.have.length(1);
19
- const { check, message, start, end } = offenses[0];
20
- expect(check).to.equal(ParserBlockingScript.meta.code);
21
- expect(message).to.contain('Use a <script> tag with async');
22
- expect(start.index).to.equal(startIndex);
23
- expect(end.index).to.equal(endIndex);
24
- });
25
-
26
6
  it('should report the correct offense when using the script tag', async () => {
27
7
  const file = `
28
8
  <script src="https://foo.bar/baz.js"></script>
@@ -45,104 +25,6 @@ describe('Module: ParserBlockingScript', () => {
45
25
  expect(end.index).to.equal(endIndex);
46
26
  });
47
27
 
48
- describe('Case: LiquidFilter corrections', () => {
49
- it('should suggest to replace a LiquidVariableOutput with a script tag that has the expression as URL', async () => {
50
- const file = "{{ 'asset' | script_tag }}";
51
- const offenses = await reportOffenses(
52
- {
53
- 'code.liquid': file,
54
- },
55
- [ParserBlockingScript],
56
- );
57
-
58
- expect(offenses).to.have.length(1);
59
- const offense = offenses[0]!;
60
- expect(offense).to.suggest(file, `Use an HTML script tag with the defer attribute instead`, {
61
- startIndex: 0,
62
- endIndex: file.length,
63
- insert: `<script src="{{ 'asset' }}" defer></script>`,
64
- });
65
- expect(offense).to.suggest(file, `Use an HTML script tag with the async attribute instead`, {
66
- startIndex: 0,
67
- endIndex: file.length,
68
- insert: `<script src="{{ 'asset' }}" async></script>`,
69
- });
70
-
71
- const suggestions = applySuggestions(file, offense);
72
- expect(suggestions).to.include(`<script src="{{ 'asset' }}" defer></script>`);
73
- expect(suggestions).to.include(`<script src="{{ 'asset' }}" async></script>`);
74
- });
75
-
76
- it('should suggest to replace a LiquidVariableOutput with a script tag that has the expression and previous filters as URL', async () => {
77
- const file = "{{ 'asset' | asset_url | script_tag }}";
78
- const offenses = await reportOffenses(
79
- {
80
- 'code.liquid': file,
81
- },
82
- [ParserBlockingScript],
83
- );
84
-
85
- expect(offenses).to.have.length(1);
86
- const offense = offenses[0];
87
- expect(offense).to.suggest(file, `Use an HTML script tag with the defer attribute instead`, {
88
- startIndex: 0,
89
- endIndex: file.length,
90
- insert: `<script src="{{ 'asset' | asset_url }}" defer></script>`,
91
- });
92
- expect(offense).to.suggest(file, `Use an HTML script tag with the async attribute instead`, {
93
- startIndex: 0,
94
- endIndex: file.length,
95
- insert: `<script src="{{ 'asset' | asset_url }}" async></script>`,
96
- });
97
-
98
- const suggestions = applySuggestions(file, offense);
99
- expect(suggestions).to.include(`<script src="{{ 'asset' | asset_url }}" defer></script>`);
100
- expect(suggestions).to.include(`<script src="{{ 'asset' | asset_url }}" async></script>`);
101
- });
102
-
103
- it('should not suggest anything if the script_tag appears in an echo tag', async () => {
104
- const file = "{% echo 'asset' | asset_url | script_tag %}";
105
- const offenses = await reportOffenses(
106
- {
107
- 'code.liquid': file,
108
- },
109
- [ParserBlockingScript],
110
- );
111
-
112
- expect(offenses).to.have.length(1);
113
- const { suggest } = offenses[0];
114
- expect(suggest).not.to.exist;
115
- });
116
-
117
- it('should not suggest anything if the script_tag appears in an assign tag', async () => {
118
- const file = "{% assign script = 'asset' | asset_url | script_tag %}";
119
- const offenses = await reportOffenses(
120
- {
121
- 'code.liquid': file,
122
- },
123
- [ParserBlockingScript],
124
- );
125
-
126
- expect(offenses).to.have.length(1);
127
- const { suggest } = offenses[0];
128
- expect(suggest).not.to.exist;
129
- });
130
-
131
- it('should not suggest anything if the script_tag appears in a liquid tag', async () => {
132
- const file = "{% liquid\necho 'asset' | asset_url | script_tag %}";
133
- const offenses = await reportOffenses(
134
- {
135
- 'code.liquid': file,
136
- },
137
- [ParserBlockingScript],
138
- );
139
-
140
- expect(offenses).to.have.length(1);
141
- const { suggest } = offenses[0];
142
- expect(suggest).not.to.exist;
143
- });
144
- });
145
-
146
28
  describe('Case: script tag suggestion', () => {
147
29
  it('should suggest adding both attributes at the end', async () => {
148
30
  const file = `<script src="a.js"></script>`;
@@ -1,8 +1,6 @@
1
- import { NodeTypes } from '@platformos/liquid-html-parser';
2
1
  import { LiquidCheckDefinition, Severity, SourceCodeType } from '../../types';
3
- import { last } from '../../utils';
4
2
  import { hasAttributeValueOf, isAttr, isHtmlAttribute, isValuedHtmlAttribute } from '../utils';
5
- import { liquidFilterSuggestion, scriptTagSuggestion } from './suggestions';
3
+ import { scriptTagSuggestion } from './suggestions';
6
4
 
7
5
  export const ParserBlockingScript: LiquidCheckDefinition = {
8
6
  meta: {
@@ -10,9 +8,9 @@ export const ParserBlockingScript: LiquidCheckDefinition = {
10
8
  aliases: ['ParserBlockingScriptTag'],
11
9
  name: 'Avoid parser blocking scripts',
12
10
  docs: {
13
- description: 'They are bad ok?',
11
+ description: 'Parser-blocking scripts delay page rendering by blocking the HTML parser.',
14
12
  recommended: true,
15
- url: 'https://shopify.dev/docs/storefronts/themes/tools/theme-check/checks/parser-blocking-javascript',
13
+ url: 'https://documentation.platformos.com/developer-guide/platformos-check/checks/parser-blocking-script',
16
14
  },
17
15
  type: SourceCodeType.LiquidHtml,
18
16
  severity: Severity.ERROR,
@@ -22,34 +20,6 @@ export const ParserBlockingScript: LiquidCheckDefinition = {
22
20
 
23
21
  create(context) {
24
22
  return {
25
- // {{ 'asset' | asset_url | script_tag }}
26
- LiquidFilter: async (node, ancestors) => {
27
- if (node.name !== 'script_tag') return;
28
-
29
- const filterString = node.source.slice(node.position.start, node.position.end);
30
- const offset = filterString.indexOf('script_tag');
31
- const parentNode = last(ancestors);
32
- const grandParentNode = last(ancestors, -1);
33
-
34
- context.report({
35
- message:
36
- 'The script_tag filter is parser-blocking. Use a <script> tag with async or defer for better performance',
37
- startIndex: node.position.start + offset,
38
- endIndex: node.position.end,
39
- suggest:
40
- grandParentNode &&
41
- grandParentNode.type === NodeTypes.LiquidVariableOutput &&
42
- parentNode &&
43
- parentNode.type === NodeTypes.LiquidVariable &&
44
- last(parentNode.filters) === node
45
- ? [
46
- liquidFilterSuggestion('defer', node, parentNode, grandParentNode),
47
- liquidFilterSuggestion('async', node, parentNode, grandParentNode),
48
- ]
49
- : undefined,
50
- });
51
- },
52
-
53
23
  // <script src="...">
54
24
  HtmlRawNode: async (node) => {
55
25
  if (node.name !== 'script') {