@platformos/platformos-check-common 0.0.7 → 0.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (309) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/AugmentedPlatformOSDocset.d.ts +11 -0
  3. package/dist/AugmentedPlatformOSDocset.js +81 -0
  4. package/dist/AugmentedPlatformOSDocset.js.map +1 -0
  5. package/dist/JSONValidator.js +1 -1
  6. package/dist/JSONValidator.js.map +1 -1
  7. package/dist/checks/deprecated-filter/index.js +4 -41
  8. package/dist/checks/deprecated-filter/index.js.map +1 -1
  9. package/dist/checks/deprecated-tag/index.js +21 -22
  10. package/dist/checks/deprecated-tag/index.js.map +1 -1
  11. package/dist/checks/duplicate-function-arguments/index.js +1 -1
  12. package/dist/checks/duplicate-function-arguments/index.js.map +1 -1
  13. package/dist/checks/duplicate-render-partial-arguments/index.js +1 -1
  14. package/dist/checks/duplicate-render-partial-arguments/index.js.map +1 -1
  15. package/dist/checks/graphql/index.js +1 -1
  16. package/dist/checks/graphql/index.js.map +1 -1
  17. package/dist/checks/img-width-and-height/index.js +1 -1
  18. package/dist/checks/img-width-and-height/index.js.map +1 -1
  19. package/dist/checks/index.d.ts +3 -3
  20. package/dist/checks/index.js +4 -79
  21. package/dist/checks/index.js.map +1 -1
  22. package/dist/checks/json-syntax-error/index.js +1 -1
  23. package/dist/checks/json-syntax-error/index.js.map +1 -1
  24. package/dist/checks/liquid-html-syntax-error/index.js +2 -2
  25. package/dist/checks/liquid-html-syntax-error/index.js.map +1 -1
  26. package/dist/checks/matching-translations/index.d.ts +2 -2
  27. package/dist/checks/matching-translations/index.js +20 -31
  28. package/dist/checks/matching-translations/index.js.map +1 -1
  29. package/dist/checks/metadata-params/index.js +6 -3
  30. package/dist/checks/metadata-params/index.js.map +1 -1
  31. package/dist/checks/missing-asset/index.js +1 -1
  32. package/dist/checks/missing-asset/index.js.map +1 -1
  33. package/dist/checks/missing-partial/index.d.ts +6 -0
  34. package/dist/checks/missing-partial/index.js +70 -0
  35. package/dist/checks/missing-partial/index.js.map +1 -0
  36. package/dist/checks/orphaned-partial/index.js +4 -4
  37. package/dist/checks/orphaned-partial/index.js.map +1 -1
  38. package/dist/checks/parser-blocking-script/index.js +10 -36
  39. package/dist/checks/parser-blocking-script/index.js.map +1 -1
  40. package/dist/checks/parser-blocking-script/suggestions.d.ts +1 -2
  41. package/dist/checks/parser-blocking-script/suggestions.js +1 -11
  42. package/dist/checks/parser-blocking-script/suggestions.js.map +1 -1
  43. package/dist/checks/reserved-doc-param-names/index.js +6 -5
  44. package/dist/checks/reserved-doc-param-names/index.js.map +1 -1
  45. package/dist/checks/translation-key-exists/index.js +1 -1
  46. package/dist/checks/translation-key-exists/index.js.map +1 -1
  47. package/dist/checks/unclosed-html-element/index.js +5 -1
  48. package/dist/checks/unclosed-html-element/index.js.map +1 -1
  49. package/dist/checks/undefined-object/index.js +7 -30
  50. package/dist/checks/undefined-object/index.js.map +1 -1
  51. package/dist/checks/unique-doc-param-names/index.js +1 -1
  52. package/dist/checks/unique-doc-param-names/index.js.map +1 -1
  53. package/dist/checks/unknown-filter/index.js +3 -3
  54. package/dist/checks/unknown-filter/index.js.map +1 -1
  55. package/dist/checks/unknown-property/index.js +1 -1
  56. package/dist/checks/unknown-property/index.js.map +1 -1
  57. package/dist/checks/unrecognized-render-partial-arguments/index.js +2 -2
  58. package/dist/checks/unrecognized-render-partial-arguments/index.js.map +1 -1
  59. package/dist/checks/unused-assign/index.js +1 -1
  60. package/dist/checks/unused-assign/index.js.map +1 -1
  61. package/dist/checks/unused-doc-param/index.js +1 -1
  62. package/dist/checks/unused-doc-param/index.js.map +1 -1
  63. package/dist/checks/utils.js +1 -1
  64. package/dist/checks/utils.js.map +1 -1
  65. package/dist/checks/valid-content-for-arguments/index.js +1 -1
  66. package/dist/checks/valid-content-for-arguments/index.js.map +1 -1
  67. package/dist/checks/valid-doc-param-types/index.js +4 -4
  68. package/dist/checks/valid-doc-param-types/index.js.map +1 -1
  69. package/dist/checks/valid-html-translation/index.d.ts +2 -2
  70. package/dist/checks/valid-html-translation/index.js +4 -4
  71. package/dist/checks/valid-html-translation/index.js.map +1 -1
  72. package/dist/checks/valid-json/index.js +1 -1
  73. package/dist/checks/valid-json/index.js.map +1 -1
  74. package/dist/checks/valid-render-partial-argument-types/index.js +2 -2
  75. package/dist/checks/valid-render-partial-argument-types/index.js.map +1 -1
  76. package/dist/checks/variable-name/index.js +1 -1
  77. package/dist/checks/variable-name/index.js.map +1 -1
  78. package/dist/context-utils.d.ts +2 -7
  79. package/dist/context-utils.js +39 -109
  80. package/dist/context-utils.js.map +1 -1
  81. package/dist/disabled-checks/index.js +4 -2
  82. package/dist/disabled-checks/index.js.map +1 -1
  83. package/dist/doc-generator/DocBlockGenerator.d.ts +16 -0
  84. package/dist/doc-generator/DocBlockGenerator.js +464 -0
  85. package/dist/doc-generator/DocBlockGenerator.js.map +1 -0
  86. package/dist/doc-generator/index.d.ts +1 -0
  87. package/dist/doc-generator/index.js +6 -0
  88. package/dist/doc-generator/index.js.map +1 -0
  89. package/dist/find-root.d.ts +7 -10
  90. package/dist/find-root.js +10 -17
  91. package/dist/find-root.js.map +1 -1
  92. package/dist/fixes/autofix.d.ts +4 -4
  93. package/dist/fixes/autofix.js +2 -2
  94. package/dist/fixes/autofix.js.map +1 -1
  95. package/dist/fixes/correctors/index.js +4 -0
  96. package/dist/fixes/correctors/index.js.map +1 -1
  97. package/dist/index.d.ts +4 -5
  98. package/dist/index.js +34 -17
  99. package/dist/index.js.map +1 -1
  100. package/dist/jsonc/parse.d.ts +1 -1
  101. package/dist/jsonc/parse.js +1 -1
  102. package/dist/liquid-doc/arguments.d.ts +7 -8
  103. package/dist/liquid-doc/arguments.js +20 -28
  104. package/dist/liquid-doc/arguments.js.map +1 -1
  105. package/dist/liquid-doc/liquidDoc.d.ts +1 -1
  106. package/dist/liquid-doc/liquidDoc.js.map +1 -1
  107. package/dist/liquid-doc/utils.d.ts +1 -1
  108. package/dist/liquid-doc/utils.js +4 -3
  109. package/dist/liquid-doc/utils.js.map +1 -1
  110. package/dist/path.d.ts +1 -0
  111. package/dist/path.js +5 -1
  112. package/dist/path.js.map +1 -1
  113. package/dist/test/MockApp.d.ts +16 -0
  114. package/dist/test/MockApp.js +16 -0
  115. package/dist/test/MockApp.js.map +1 -0
  116. package/dist/test/MockFileSystem.d.ts +3 -3
  117. package/dist/test/MockFileSystem.js +6 -6
  118. package/dist/test/MockFileSystem.js.map +1 -1
  119. package/dist/test/index.d.ts +1 -1
  120. package/dist/test/index.js +1 -1
  121. package/dist/test/index.js.map +1 -1
  122. package/dist/test/test-helper.d.ts +10 -9
  123. package/dist/test/test-helper.js +15 -106
  124. package/dist/test/test-helper.js.map +1 -1
  125. package/dist/to-schema.d.ts +1 -1
  126. package/dist/to-source-code.d.ts +3 -2
  127. package/dist/to-source-code.js +20 -0
  128. package/dist/to-source-code.js.map +1 -1
  129. package/dist/tsconfig.tsbuildinfo +1 -1
  130. package/dist/types/platformos-liquid-docs.d.ts +128 -0
  131. package/dist/types/platformos-liquid-docs.js +3 -0
  132. package/dist/types/platformos-liquid-docs.js.map +1 -0
  133. package/dist/types/schemas/index.d.ts +0 -2
  134. package/dist/types/schemas/index.js.map +1 -1
  135. package/dist/types.d.ts +18 -67
  136. package/dist/types.js +3 -5
  137. package/dist/types.js.map +1 -1
  138. package/dist/utils/block.js.map +1 -1
  139. package/dist/utils/index.d.ts +0 -1
  140. package/dist/utils/index.js +0 -1
  141. package/dist/utils/index.js.map +1 -1
  142. package/dist/yaml/parse.d.ts +5 -0
  143. package/dist/yaml/parse.js +94 -0
  144. package/dist/yaml/parse.js.map +1 -0
  145. package/package.json +4 -3
  146. package/src/{AugmentedThemeDocset.spec.ts → AugmentedPlatformOSDocset.spec.ts} +47 -34
  147. package/src/AugmentedPlatformOSDocset.ts +89 -0
  148. package/src/JSONValidator.ts +1 -1
  149. package/src/checks/deprecated-filter/index.spec.ts +76 -248
  150. package/src/checks/deprecated-filter/index.ts +5 -53
  151. package/src/checks/deprecated-tag/index.spec.ts +85 -34
  152. package/src/checks/deprecated-tag/index.ts +27 -22
  153. package/src/checks/duplicate-function-arguments/index.ts +1 -1
  154. package/src/checks/duplicate-render-partial-arguments/index.ts +1 -1
  155. package/src/checks/graphql/index.ts +1 -1
  156. package/src/checks/img-width-and-height/index.ts +1 -1
  157. package/src/checks/index.ts +11 -80
  158. package/src/checks/invalid-hash-assign-target/index.spec.ts +14 -14
  159. package/src/checks/json-syntax-error/index.ts +1 -1
  160. package/src/checks/liquid-html-syntax-error/checks/InvalidBooleanExpression.spec.ts +0 -11
  161. package/src/checks/liquid-html-syntax-error/checks/InvalidLoopArguments.spec.ts +1 -2
  162. package/src/checks/liquid-html-syntax-error/index.spec.ts +1 -6
  163. package/src/checks/liquid-html-syntax-error/index.ts +2 -2
  164. package/src/checks/matching-translations/index.spec.ts +89 -346
  165. package/src/checks/matching-translations/index.ts +24 -35
  166. package/src/checks/metadata-params/index.ts +5 -7
  167. package/src/checks/missing-asset/index.ts +1 -1
  168. package/src/checks/{missing-template → missing-partial}/index.spec.ts +6 -6
  169. package/src/checks/{missing-template → missing-partial}/index.ts +6 -20
  170. package/src/checks/orphaned-partial/index.ts +3 -3
  171. package/src/checks/parser-blocking-script/index.spec.ts +0 -118
  172. package/src/checks/parser-blocking-script/index.ts +3 -33
  173. package/src/checks/parser-blocking-script/suggestions.ts +1 -28
  174. package/src/checks/translation-key-exists/index.ts +1 -1
  175. package/src/checks/unclosed-html-element/index.ts +5 -1
  176. package/src/checks/undefined-object/index.spec.ts +3 -109
  177. package/src/checks/undefined-object/index.ts +8 -33
  178. package/src/checks/unique-doc-param-names/index.ts +1 -1
  179. package/src/checks/unknown-filter/index.spec.ts +2 -2
  180. package/src/checks/unknown-filter/index.ts +3 -3
  181. package/src/checks/unknown-property/index.ts +1 -1
  182. package/src/checks/unrecognized-render-partial-arguments/index.spec.ts +5 -5
  183. package/src/checks/unrecognized-render-partial-arguments/index.ts +2 -5
  184. package/src/checks/unused-assign/index.spec.ts +0 -30
  185. package/src/checks/unused-assign/index.ts +1 -1
  186. package/src/checks/unused-doc-param/index.ts +1 -1
  187. package/src/checks/utils.ts +1 -1
  188. package/src/checks/valid-doc-param-types/index.ts +4 -4
  189. package/src/checks/valid-html-translation/index.spec.ts +42 -32
  190. package/src/checks/valid-html-translation/index.ts +7 -7
  191. package/src/checks/valid-json/index.ts +1 -1
  192. package/src/checks/valid-render-partial-argument-types/index.ts +2 -5
  193. package/src/checks/variable-name/index.ts +1 -1
  194. package/src/context-utils.spec.ts +49 -77
  195. package/src/context-utils.ts +39 -128
  196. package/src/disabled-checks/index.spec.ts +35 -0
  197. package/src/disabled-checks/index.ts +4 -2
  198. package/src/find-root.ts +12 -22
  199. package/src/fixes/autofix.spec.ts +2 -2
  200. package/src/fixes/autofix.ts +4 -4
  201. package/src/fixes/correctors/index.ts +4 -0
  202. package/src/ignore.spec.ts +0 -1
  203. package/src/index.ts +33 -21
  204. package/src/jsonc/parse.ts +1 -1
  205. package/src/liquid-doc/arguments.spec.ts +19 -45
  206. package/src/liquid-doc/arguments.ts +26 -39
  207. package/src/liquid-doc/liquidDoc.ts +1 -2
  208. package/src/liquid-doc/utils.ts +4 -3
  209. package/src/path.ts +1 -0
  210. package/src/test/{MockTheme.ts → MockApp.ts} +1 -1
  211. package/src/test/MockFileSystem.ts +6 -6
  212. package/src/test/index.ts +1 -1
  213. package/src/test/test-helper.ts +29 -127
  214. package/src/to-source-code.ts +20 -1
  215. package/src/types/{theme-liquid-docs.ts → platformos-liquid-docs.ts} +8 -13
  216. package/src/types/schemas/index.ts +0 -2
  217. package/src/types.ts +21 -92
  218. package/src/utils/index.ts +0 -1
  219. package/src/yaml/parse.ts +111 -0
  220. package/src/AugmentedThemeDocset.ts +0 -137
  221. package/src/checks/app-block-missing-schema/index.spec.ts +0 -121
  222. package/src/checks/app-block-missing-schema/index.ts +0 -46
  223. package/src/checks/app-block-valid-tags/index.spec.ts +0 -96
  224. package/src/checks/app-block-valid-tags/index.ts +0 -54
  225. package/src/checks/asset-preload/index.spec.ts +0 -78
  226. package/src/checks/asset-preload/index.ts +0 -65
  227. package/src/checks/asset-size-app-block-css/index.spec.ts +0 -88
  228. package/src/checks/asset-size-app-block-css/index.ts +0 -78
  229. package/src/checks/asset-size-app-block-javascript/index.spec.ts +0 -66
  230. package/src/checks/asset-size-app-block-javascript/index.ts +0 -78
  231. package/src/checks/asset-size-css/index.spec.ts +0 -166
  232. package/src/checks/asset-size-css/index.ts +0 -160
  233. package/src/checks/asset-size-javascript/index.spec.ts +0 -184
  234. package/src/checks/asset-size-javascript/index.ts +0 -144
  235. package/src/checks/block-id-usage/index.spec.ts +0 -76
  236. package/src/checks/block-id-usage/index.ts +0 -72
  237. package/src/checks/cdn-preconnect/index.spec.ts +0 -40
  238. package/src/checks/cdn-preconnect/index.ts +0 -43
  239. package/src/checks/content-for-header-modification/index.spec.ts +0 -65
  240. package/src/checks/content-for-header-modification/index.ts +0 -72
  241. package/src/checks/deprecate-bgsizes/index.spec.ts +0 -41
  242. package/src/checks/deprecate-bgsizes/index.ts +0 -49
  243. package/src/checks/deprecate-lazysizes/index.spec.ts +0 -26
  244. package/src/checks/deprecate-lazysizes/index.ts +0 -58
  245. package/src/checks/deprecated-filter/fixes.ts +0 -264
  246. package/src/checks/deprecated-fonts-on-sections-and-blocks/deprecated-fonts-data.ts +0 -1343
  247. package/src/checks/deprecated-fonts-on-sections-and-blocks/index.spec.ts +0 -613
  248. package/src/checks/deprecated-fonts-on-sections-and-blocks/index.ts +0 -284
  249. package/src/checks/deprecated-fonts-on-settings-schema/index.spec.ts +0 -102
  250. package/src/checks/deprecated-fonts-on-settings-schema/index.ts +0 -66
  251. package/src/checks/duplicate-content-for-arguments/index.spec.ts +0 -98
  252. package/src/checks/duplicate-content-for-arguments/index.ts +0 -43
  253. package/src/checks/empty-block-content/index.spec.ts +0 -117
  254. package/src/checks/empty-block-content/index.ts +0 -60
  255. package/src/checks/hardcoded-routes/index.spec.ts +0 -58
  256. package/src/checks/hardcoded-routes/index.ts +0 -100
  257. package/src/checks/json-missing-block/index.spec.ts +0 -435
  258. package/src/checks/json-missing-block/index.ts +0 -56
  259. package/src/checks/json-missing-block/missing-block-utils.ts +0 -147
  260. package/src/checks/liquid-free-settings/index.spec.ts +0 -180
  261. package/src/checks/liquid-free-settings/index.ts +0 -79
  262. package/src/checks/missing-content-for-arguments/index.spec.ts +0 -144
  263. package/src/checks/missing-content-for-arguments/index.ts +0 -46
  264. package/src/checks/pagination-size/index.spec.ts +0 -158
  265. package/src/checks/pagination-size/index.ts +0 -104
  266. package/src/checks/remote-asset/index.spec.ts +0 -280
  267. package/src/checks/remote-asset/index.ts +0 -238
  268. package/src/checks/reserved-doc-param-names/index.spec.ts +0 -62
  269. package/src/checks/reserved-doc-param-names/index.ts +0 -57
  270. package/src/checks/schema-presets-block-order/index.spec.ts +0 -344
  271. package/src/checks/schema-presets-block-order/index.ts +0 -154
  272. package/src/checks/schema-presets-static-blocks/index.spec.ts +0 -145
  273. package/src/checks/schema-presets-static-blocks/index.ts +0 -126
  274. package/src/checks/static-stylesheet-and-javascript-tags/index.spec.ts +0 -257
  275. package/src/checks/static-stylesheet-and-javascript-tags/index.ts +0 -48
  276. package/src/checks/unique-settings-id/index.spec.ts +0 -24
  277. package/src/checks/unique-settings-id/index.ts +0 -84
  278. package/src/checks/unique-settings-id/test-data.ts +0 -1191
  279. package/src/checks/unique-static-block-id/index.spec.ts +0 -55
  280. package/src/checks/unique-static-block-id/index.ts +0 -60
  281. package/src/checks/unrecognized-content-for-arguments/index.spec.ts +0 -145
  282. package/src/checks/unrecognized-content-for-arguments/index.ts +0 -55
  283. package/src/checks/valid-block-target/index.spec.ts +0 -1396
  284. package/src/checks/valid-block-target/index.ts +0 -142
  285. package/src/checks/valid-content-for-argument-types/index.spec.ts +0 -382
  286. package/src/checks/valid-content-for-argument-types/index.ts +0 -42
  287. package/src/checks/valid-content-for-arguments/index.spec.ts +0 -107
  288. package/src/checks/valid-content-for-arguments/index.ts +0 -98
  289. package/src/checks/valid-local-blocks/index.spec.ts +0 -286
  290. package/src/checks/valid-local-blocks/index.ts +0 -100
  291. package/src/checks/valid-local-blocks/valid-block-utils.ts +0 -97
  292. package/src/checks/valid-schema/index.spec.ts +0 -174
  293. package/src/checks/valid-schema/index.ts +0 -41
  294. package/src/checks/valid-schema-name/index.spec.ts +0 -112
  295. package/src/checks/valid-schema-name/index.ts +0 -75
  296. package/src/checks/valid-settings-key/index.spec.ts +0 -321
  297. package/src/checks/valid-settings-key/index.ts +0 -144
  298. package/src/checks/valid-static-block-type/index.spec.ts +0 -38
  299. package/src/checks/valid-static-block-type/index.ts +0 -58
  300. package/src/checks/valid-visible-if/index.spec.ts +0 -619
  301. package/src/checks/valid-visible-if/index.ts +0 -184
  302. package/src/checks/valid-visible-if/visible-if-utils.ts +0 -158
  303. package/src/tags/content-for.ts +0 -25
  304. package/src/to-schema.ts +0 -231
  305. package/src/types/schemas/section.ts +0 -86
  306. package/src/types/schemas/theme-block.ts +0 -34
  307. package/src/types/theme-schemas.ts +0 -80
  308. package/src/utils/block.ts +0 -300
  309. package/src/utils/markup.ts +0 -10
@@ -0,0 +1,111 @@
1
+ import { isMap, isScalar, isSeq, isPair, parseDocument } from 'yaml';
2
+ import type { Pair, Scalar, YAMLMap, YAMLSeq } from 'yaml';
3
+ import type {
4
+ ArrayNode,
5
+ IdentifierNode,
6
+ JSONNode,
7
+ LiteralNode,
8
+ Location,
9
+ ObjectNode,
10
+ PropertyNode,
11
+ ValueNode,
12
+ } from '../jsonc/types';
13
+
14
+ export class YAMLConvertError extends Error {
15
+ constructor(message: string) {
16
+ super(message);
17
+ this.name = 'YAMLConvertError';
18
+ }
19
+ }
20
+
21
+ function loc(start: number, end: number): Location {
22
+ return { start: { offset: start }, end: { offset: end } };
23
+ }
24
+
25
+ function getRange(node: any): [number, number] {
26
+ if (node && node.range && Array.isArray(node.range)) {
27
+ const start = node.range[0] ?? 0;
28
+ const end = node.range[1] ?? 0;
29
+ return [start, end];
30
+ }
31
+ return [0, 0];
32
+ }
33
+
34
+ export function toYAMLNode(source: string): JSONNode {
35
+ const doc = parseDocument(source);
36
+
37
+ if (doc.errors.length > 0) {
38
+ throw new YAMLConvertError(doc.errors[0].message);
39
+ }
40
+
41
+ if (doc.contents === null || doc.contents === undefined) {
42
+ return { type: 'Object', children: [], loc: loc(0, 0) } as ObjectNode;
43
+ }
44
+
45
+ return convertNode(doc.contents as any, source) as JSONNode;
46
+ }
47
+
48
+ function convertNode(node: any, source: string): JSONNode {
49
+ if (isMap(node)) return convertMap(node, source);
50
+ if (isSeq(node)) return convertSeq(node, source);
51
+ if (isScalar(node)) return convertScalar(node);
52
+ return { type: 'Literal', value: null, raw: 'null', loc: loc(0, 0) } as LiteralNode;
53
+ }
54
+
55
+ function convertMap(node: YAMLMap, source: string): ObjectNode {
56
+ const [start, end] = getRange(node);
57
+ return {
58
+ type: 'Object',
59
+ children: node.items.map((pair) => convertPair(pair as Pair<any, any>, source)),
60
+ loc: loc(start, end),
61
+ };
62
+ }
63
+
64
+ function convertPair(pair: Pair<any, any>, source: string): PropertyNode {
65
+ const key = pair.key as Scalar;
66
+ const value = pair.value;
67
+
68
+ const [keyStart, keyEnd] = getRange(key);
69
+ const [, valueEnd] = value ? getRange(value) : [keyEnd, keyEnd];
70
+ const pairEnd = valueEnd > keyEnd ? valueEnd : keyEnd;
71
+
72
+ return {
73
+ type: 'Property',
74
+ key: convertIdentifier(key),
75
+ value: value
76
+ ? (convertNode(value, source) as ValueNode)
77
+ : ({ type: 'Literal', value: null, raw: 'null', loc: loc(keyEnd, keyEnd) } as LiteralNode),
78
+ loc: loc(keyStart, pairEnd),
79
+ };
80
+ }
81
+
82
+ function convertIdentifier(node: Scalar): IdentifierNode {
83
+ const [start, end] = getRange(node);
84
+ const value = String(node.value ?? '');
85
+ return {
86
+ type: 'Identifier',
87
+ value,
88
+ raw: JSON.stringify(value),
89
+ loc: loc(start, end),
90
+ };
91
+ }
92
+
93
+ function convertScalar(node: Scalar): LiteralNode {
94
+ const [start, end] = getRange(node);
95
+ const value = node.value as string | number | boolean | null;
96
+ return {
97
+ type: 'Literal',
98
+ value,
99
+ raw: JSON.stringify(value),
100
+ loc: loc(start, end),
101
+ };
102
+ }
103
+
104
+ function convertSeq(node: YAMLSeq, source: string): ArrayNode {
105
+ const [start, end] = getRange(node);
106
+ return {
107
+ type: 'Array',
108
+ children: node.items.map((item) => convertNode(item, source) as ValueNode),
109
+ loc: loc(start, end),
110
+ };
111
+ }
@@ -1,137 +0,0 @@
1
- import {
2
- Access,
3
- FilterEntry,
4
- ObjectEntry,
5
- TagEntry,
6
- ThemeDocset,
7
- Translations,
8
- ReturnType,
9
- } from './types';
10
- import { memo } from './utils';
11
-
12
- const toFilterEntry = (name: string): FilterEntry => ({ name });
13
-
14
- const expandAliases = (entries: FilterEntry[]): FilterEntry[] => {
15
- return entries.flatMap((entry) => {
16
- const aliases: string[] = (entry as any).aliases ?? [];
17
- return aliases.map((alias) => ({ ...entry, name: alias }));
18
- });
19
- };
20
-
21
- const undocumentedFilters = [
22
- '_online_store_editor_live_setting',
23
- 'addresses_url',
24
- 'app_block_path?',
25
- 'app_block_path_for',
26
- 'app_extension_path?',
27
- 'app_snippet_path?',
28
- 'cancel_customer_order_link',
29
- 'debug',
30
- 'delete_customer_address_link',
31
- 'dev_shop?',
32
- 'distance_from',
33
- 'edit_customer_address_link',
34
- 'encode_url_component',
35
- 'excerpt',
36
- 'format_code',
37
- 'global_block_type?',
38
- 'h',
39
- 'handle_from',
40
- 'installments_pricing',
41
- 'link_to_theme',
42
- 'login_button',
43
- 'login_url',
44
- 'logout_url',
45
- 'pad_spaces',
46
- 'paragraphize',
47
- 'recover_password_link',
48
- 'recover_url',
49
- 'register_url',
50
- 'registration_uuid_from',
51
- 'root_account_url',
52
- 'sentence',
53
- 'theme_url',
54
- 'unit',
55
- 'weight',
56
- ];
57
-
58
- const undocumentedObjectEntryKeys = [
59
- 'locale',
60
- 'direction',
61
- 'skip_to_content_link',
62
- 'checkout_html_classes',
63
- 'checkout_stylesheets',
64
- 'checkout_scripts',
65
- 'content_for_logo',
66
- 'breadcrumb',
67
- 'order_summary_toggle',
68
- 'content_for_order_summary',
69
- 'alternative_payment_methods',
70
- 'content_for_footer',
71
- 'tracking_code',
72
- ];
73
-
74
- const toObjectEntry = (name: string, access?: Access, returnType?: ReturnType[]): ObjectEntry => ({
75
- name,
76
- ...(access && { access }),
77
- ...(returnType && { return_type: returnType }),
78
- });
79
-
80
- const undocumentedObjects = ['customer_address', 'product_variant'];
81
- const legacyCheckoutEntries: ObjectEntry[] = undocumentedObjectEntryKeys.map((objectKey) =>
82
- toObjectEntry(objectKey, { global: false, parents: [], template: [] }, [
83
- { type: 'string', name: '' },
84
- ]),
85
- );
86
-
87
- const toTagEntry = (name: string): TagEntry => ({ name });
88
- const undocumentedTags = ['elsif', 'ifchanged', 'when', 'schema'];
89
-
90
- export class AugmentedThemeDocset implements ThemeDocset {
91
- constructor(private themeDocset: ThemeDocset) {}
92
- graphQL = memo(async (): Promise<string | null> => {
93
- return await this.themeDocset.graphQL();
94
- });
95
-
96
- public isAugmented = true;
97
-
98
- filters = memo(async (): Promise<FilterEntry[]> => {
99
- const officialFilters = await this.themeDocset.filters();
100
- return [
101
- ...officialFilters,
102
- ...expandAliases(officialFilters),
103
- ...undocumentedFilters.map(toFilterEntry),
104
- ];
105
- });
106
-
107
- objects = memo(async (): Promise<ObjectEntry[]> => {
108
- return [
109
- ...(await this.themeDocset.objects()),
110
- ...undocumentedObjects.map((obj) => toObjectEntry(obj)),
111
- ...legacyCheckoutEntries,
112
- ];
113
- });
114
-
115
- liquidDrops = memo(async (): Promise<ObjectEntry[]> => {
116
- return (await this.themeDocset.objects()).filter((obj) => {
117
- if (!obj.access) {
118
- return true;
119
- }
120
-
121
- if (obj.deprecated) {
122
- return false;
123
- }
124
-
125
- // objects that are accessible outside Global context
126
- return !obj.access.global || (obj.access.global && obj.access.parents.length > 0);
127
- });
128
- });
129
-
130
- tags = memo(async (): Promise<TagEntry[]> => {
131
- return [...(await this.themeDocset.tags()), ...undocumentedTags.map(toTagEntry)];
132
- });
133
-
134
- systemTranslations = memo(async (): Promise<Translations> => {
135
- return this.themeDocset.systemTranslations();
136
- });
137
- }
@@ -1,121 +0,0 @@
1
- import { describe, expect, it } from 'vitest';
2
- import { runLiquidCheck } from '../../test';
3
- import { AppBlockMissingSchema } from './index';
4
-
5
- describe('AppBlockMissingSchema', () => {
6
- it('should report an error when schema tag is missing on a theme app extension (blocks only)', async () => {
7
- const sourceCode = `
8
- <footer class="footer">
9
- {% for block in section.blocks %}
10
- {% case block.type %}
11
- {% when 'link' %}
12
- <div class="link" {{ block.shopify_attributes }}>
13
- {{ block.settings.linktext | link_to: block.settings.linkurl }}
14
- </div>
15
-
16
- {% when 'custom-text' %}
17
- <div class="text" {{ block.shopify_attributes }}>
18
- {{ block.settings.custom-text-field }}
19
- </div>
20
- {% endcase %}
21
- {% endfor %}
22
- </footer>
23
- `;
24
-
25
- const offenses = await runLiquidCheck(
26
- AppBlockMissingSchema,
27
- sourceCode,
28
- 'blocks/footer.liquid',
29
- );
30
- expect(offenses).to.have.lengthOf(1);
31
- });
32
-
33
- it('should not report an error when schema tag is missing on a snippet in a theme app extension )', async () => {
34
- const sourceCode = `
35
- <footer class="footer">
36
- {% for block in section.blocks %}
37
- {% case block.type %}
38
- {% when 'link' %}
39
- <div class="link" {{ block.shopify_attributes }}>
40
- {{ block.settings.linktext | link_to: block.settings.linkurl }}
41
- </div>
42
-
43
- {% when 'custom-text' %}
44
- <div class="text" {{ block.shopify_attributes }}>
45
- {{ block.settings.custom-text-field }}
46
- </div>
47
- {% endcase %}
48
- {% endfor %}
49
- </footer>
50
- `;
51
-
52
- const offenses = await runLiquidCheck(
53
- AppBlockMissingSchema,
54
- sourceCode,
55
- 'app/views/partials/footer.liquid',
56
- );
57
- expect(offenses).to.have.lengthOf(0);
58
- });
59
-
60
- it('should not report when the schema is present on a theme app extension', async () => {
61
- const sourceCode = `
62
- <footer class="footer">
63
- {% for block in section.blocks %}
64
- {% case block.type %}
65
- {% when 'link' %}
66
- <div class="link" {{ block.shopify_attributes }}>
67
- {{ block.settings.linktext | link_to: block.settings.linkurl }}
68
- </div>
69
-
70
- {% when 'custom-text' %}
71
- <div class="text" {{ block.shopify_attributes }}>
72
- {{ block.settings.custom-text-field }}
73
- </div>
74
- {% endcase %}
75
- {% endfor %}
76
- </footer>
77
-
78
- {% schema %}
79
- {
80
- "name": "Footer",
81
- "max_blocks": 8,
82
- "blocks": [
83
- {
84
- "type": "link",
85
- "name": "Link",
86
- "settings": [
87
- {
88
- "id": "linkurl",
89
- "type": "url",
90
- "label": "URL link"
91
- },
92
- {
93
- "id": "linktext",
94
- "type": "text",
95
- "label": "Link text"
96
- }
97
- ]
98
- },
99
- {
100
- "type": "custom-text",
101
- "name": "Custom Text",
102
- "settings": [
103
- {
104
- "id": "custom-text-field",
105
- "type": "textarea",
106
- "label": "Text"
107
- }
108
- ]
109
- }
110
- ]
111
- }
112
- {% endschema %}`;
113
-
114
- const offenses = await runLiquidCheck(
115
- AppBlockMissingSchema,
116
- sourceCode,
117
- 'blocks/footer.liquid',
118
- );
119
- expect(offenses).to.have.lengthOf(0);
120
- });
121
- });
@@ -1,46 +0,0 @@
1
- import { ConfigTarget, LiquidCheckDefinition, Severity, SourceCodeType } from '../../types';
2
-
3
- export const AppBlockMissingSchema: LiquidCheckDefinition = {
4
- meta: {
5
- code: 'AppBlockMissingSchema',
6
- name: 'Missing schema definitions in theme app extensions app blocks should be avoided',
7
- docs: {
8
- description: 'Report missing schema definitions in theme app extensions app blocks',
9
- recommended: true,
10
- url: 'https://shopify.dev/docs/storefronts/themes/tools/theme-check/checks/app-block-missing-schema',
11
- },
12
- severity: Severity.ERROR,
13
- type: SourceCodeType.LiquidHtml,
14
- schema: {},
15
- targets: [ConfigTarget.ThemeAppExtension],
16
- },
17
-
18
- create(context) {
19
- let foundSchema = false;
20
- const relativePath = context.toRelativePath(context.file.uri);
21
-
22
- /**
23
- * Theme app extension blocks are the only types of files that can have a
24
- * schema defined in them.
25
- */
26
- if (!relativePath.startsWith('blocks/')) {
27
- return {};
28
- }
29
-
30
- return {
31
- async LiquidRawTag(node) {
32
- if (node.name == 'schema') foundSchema = true;
33
- },
34
-
35
- async onCodePathEnd() {
36
- if (!foundSchema) {
37
- context.report({
38
- message: `The schema does not exist`,
39
- startIndex: 0,
40
- endIndex: 0,
41
- });
42
- }
43
- },
44
- };
45
- },
46
- };
@@ -1,96 +0,0 @@
1
- import { describe, it, expect } from 'vitest';
2
- import { runLiquidCheck } from '../../test';
3
- import { ForbiddenTag, AppBlockValidTags } from './index';
4
-
5
- const blocksFilePath = 'blocks/app.liquid';
6
-
7
- describe('Module: AppBlockValidTags', () => {
8
- it('should report an offense when the forbidden tag is used in blocks directory liquid file', async () => {
9
- const tags = ['include', 'layout', 'section', 'sections'];
10
- for (const tag of tags) {
11
- const sourceCode = `
12
- {% ${tag} 'test' %}
13
- {% schema %}
14
- { }
15
- {% endschema %}
16
- `;
17
-
18
- const offenses = await runLiquidCheck(AppBlockValidTags, sourceCode, blocksFilePath);
19
-
20
- const expectedStart = {
21
- index: 9,
22
- line: 1,
23
- character: 8,
24
- };
25
- const tagEndOffset = 13;
26
- const endOffset = tag.length + tagEndOffset;
27
-
28
- const expectedEnd = {
29
- index: expectedStart.index + endOffset,
30
- line: expectedStart.line,
31
- character: expectedStart.character + endOffset,
32
- };
33
-
34
- expect(offenses).to.have.length(1);
35
- expect(offenses).to.containOffense({
36
- check: AppBlockValidTags.meta.code,
37
- message: `Theme app extension blocks cannot contain '${tag}' tags`,
38
- uri: 'file:///blocks/app.liquid',
39
- severity: 0,
40
- start: expectedStart,
41
- end: expectedEnd,
42
- });
43
- }
44
- });
45
-
46
- it('should report an offense when the forbidden tag is used with an end tag in blocks directory liquid file', async () => {
47
- const tags = ['javascript', 'stylesheet'];
48
- for (const tag of tags) {
49
- const sourceCode = `
50
- {% ${tag} %}
51
- {% end${tag} %}
52
- {% schema %}
53
- { }
54
- {% endschema %}
55
- `;
56
-
57
- const offenses = await runLiquidCheck(AppBlockValidTags, sourceCode, blocksFilePath);
58
-
59
- const expectedStart = {
60
- index: 9,
61
- line: 1,
62
- character: 8,
63
- };
64
- const expectedEnd = {
65
- index: expectedStart.index + tag.length + 34,
66
- line: 2,
67
- character: expectedStart.character + tag.length + 9,
68
- };
69
-
70
- expect(offenses).to.have.length(1);
71
- expect(offenses).to.containOffense({
72
- check: AppBlockValidTags.meta.code,
73
- message: `Theme app extension blocks cannot contain '${tag}' tags`,
74
- uri: 'file:///blocks/app.liquid',
75
- severity: 0,
76
- start: expectedStart,
77
- end: expectedEnd,
78
- });
79
- }
80
- });
81
-
82
- it('should contain specifically the following forbidden tags', async () => {
83
- const actualTagValues = Object.values(ForbiddenTag);
84
- const expectedTagValues = [
85
- 'javascript',
86
- 'stylesheet',
87
- 'include',
88
- 'layout',
89
- 'section',
90
- 'sections',
91
- ];
92
-
93
- expectedTagValues.forEach((tag) => expect(actualTagValues).toContain(tag));
94
- expect(actualTagValues.length).toBe(expectedTagValues.length);
95
- });
96
- });
@@ -1,54 +0,0 @@
1
- import { LiquidRawTag, LiquidTag } from '@platformos/liquid-html-parser';
2
- import { ConfigTarget, LiquidCheckDefinition, Severity, SourceCodeType } from '../../types';
3
-
4
- export enum ForbiddenTag {
5
- JavaScript = 'javascript',
6
- StyleSheet = 'stylesheet',
7
- Include = 'include',
8
- Layout = 'layout',
9
- Section = 'section',
10
- Sections = 'sections',
11
- }
12
-
13
- const isForbiddenTag = (value: string): value is ForbiddenTag => {
14
- return Object.values(ForbiddenTag).includes(value as ForbiddenTag);
15
- };
16
-
17
- const buildErrorMessage = (tag: ForbiddenTag) =>
18
- `Theme app extension blocks cannot contain '${tag}' tags`;
19
-
20
- export const AppBlockValidTags: LiquidCheckDefinition = {
21
- meta: {
22
- code: 'AppBlockValidTags',
23
- name: 'App Block Valid Tags',
24
- docs: {
25
- description:
26
- 'Identifies forbidden Liquid tags in theme app extension app block and app embed block code.',
27
- url: 'https://shopify.dev/docs/storefronts/themes/tools/theme-check/checks/app-block-valid-tags',
28
- recommended: false,
29
- },
30
- type: SourceCodeType.LiquidHtml,
31
- severity: Severity.ERROR,
32
- schema: {},
33
- targets: [ConfigTarget.ThemeAppExtension],
34
- },
35
-
36
- create(context) {
37
- const handleForbiddenTags = async (node: LiquidTag | LiquidRawTag) => {
38
- if (isForbiddenTag(node.name)) {
39
- // When a forbidden tag is used to define a block section
40
- // with an end tag, highlight the whole section
41
- const endIndex = node.blockEndPosition ? node.blockEndPosition.end : node.position.end;
42
- const startIndex = node.blockStartPosition.start;
43
- const message = buildErrorMessage(node.name);
44
-
45
- return context.report({ message, startIndex, endIndex });
46
- }
47
- };
48
-
49
- return {
50
- LiquidRawTag: handleForbiddenTags,
51
- LiquidTag: handleForbiddenTags,
52
- };
53
- },
54
- };
@@ -1,78 +0,0 @@
1
- import { describe, it, expect } from 'vitest';
2
- import { runLiquidCheck, highlightedOffenses } from '../../test';
3
- import { AssetPreload } from './index';
4
-
5
- describe('Module: AssetPreload', () => {
6
- it('no offense with link element', async () => {
7
- const sourceCode = `
8
- <link href="a.css" rel="stylesheet">
9
- <link href="b.com" rel="preconnect">
10
- `;
11
-
12
- const offenses = await runLiquidCheck(AssetPreload, sourceCode);
13
- expect(offenses).to.have.lengthOf(0);
14
- });
15
-
16
- it('reports stylesheet preloading', async () => {
17
- const sourceCode = `
18
- <link href="a.css" rel="preload" as="style">
19
- `;
20
-
21
- const offenses = await runLiquidCheck(AssetPreload, sourceCode);
22
- expect(offenses).to.have.lengthOf(1);
23
- expect(offenses[0].message).to.equal(
24
- 'For better performance, prefer using the preload argument of the stylesheet_tag filter',
25
- );
26
-
27
- const highlights = highlightedOffenses({ 'file.liquid': sourceCode }, offenses);
28
- expect(highlights).to.eql([`<link href="a.css" rel="preload" as="style">`]);
29
- });
30
-
31
- it('reports image preloading', async () => {
32
- const sourceCode = `
33
- <link href="a.png" rel="preload" as="image">
34
- `;
35
-
36
- const offenses = await runLiquidCheck(AssetPreload, sourceCode);
37
- expect(offenses).to.have.lengthOf(1);
38
- expect(offenses[0].message).to.equal(
39
- 'For better performance, prefer using the preload argument of the image_tag filter',
40
- );
41
-
42
- const highlights = highlightedOffenses({ 'file.liquid': sourceCode }, offenses);
43
- expect(highlights).to.eql([`<link href="a.png" rel="preload" as="image">`]);
44
- });
45
-
46
- it('reports general preloading', async () => {
47
- const sourceCode = `
48
- <link href="a.js" rel="preload" as="script">
49
- `;
50
-
51
- const offenses = await runLiquidCheck(AssetPreload, sourceCode);
52
- expect(offenses).to.have.lengthOf(1);
53
- expect(offenses[0].message).to.equal(
54
- 'For better performance, prefer using the preload_tag filter',
55
- );
56
-
57
- const highlights = highlightedOffenses({ 'file.liquid': sourceCode }, offenses);
58
- expect(highlights).to.eql([`<link href="a.js" rel="preload" as="script">`]);
59
- });
60
-
61
- it('should report offenses for manual preloading of assets', async () => {
62
- const sourceCode = `
63
- <link href="{{ 'script.js' | asset_url }}" rel="preload" as="script">
64
- <link href="{{ 'style.css' | asset_url }}" rel="preload" as="style">
65
- <link href="{{ 'image.png' | asset_url }}" rel="preload" as="image">
66
- `;
67
-
68
- const offenses = await runLiquidCheck(AssetPreload, sourceCode);
69
- expect(offenses).to.have.lengthOf(3);
70
-
71
- const highlights = highlightedOffenses({ 'file.liquid': sourceCode }, offenses);
72
- expect(highlights).to.eql([
73
- `<link href="{{ 'script.js' | asset_url }}" rel="preload" as="script">`,
74
- `<link href="{{ 'style.css' | asset_url }}" rel="preload" as="style">`,
75
- `<link href="{{ 'image.png' | asset_url }}" rel="preload" as="image">`,
76
- ]);
77
- });
78
- });