@platformos/platformos-check-common 0.0.6 → 0.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (304) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/AugmentedPlatformOSDocset.d.ts +11 -0
  3. package/dist/AugmentedPlatformOSDocset.js +81 -0
  4. package/dist/AugmentedPlatformOSDocset.js.map +1 -0
  5. package/dist/JSONValidator.js +1 -1
  6. package/dist/JSONValidator.js.map +1 -1
  7. package/dist/checks/deprecated-filter/index.js +4 -41
  8. package/dist/checks/deprecated-filter/index.js.map +1 -1
  9. package/dist/checks/deprecated-tag/index.js +21 -22
  10. package/dist/checks/deprecated-tag/index.js.map +1 -1
  11. package/dist/checks/duplicate-function-arguments/index.js +1 -1
  12. package/dist/checks/duplicate-function-arguments/index.js.map +1 -1
  13. package/dist/checks/duplicate-render-partial-arguments/index.js +1 -1
  14. package/dist/checks/duplicate-render-partial-arguments/index.js.map +1 -1
  15. package/dist/checks/graphql/index.js +1 -1
  16. package/dist/checks/graphql/index.js.map +1 -1
  17. package/dist/checks/img-width-and-height/index.js +1 -1
  18. package/dist/checks/img-width-and-height/index.js.map +1 -1
  19. package/dist/checks/index.d.ts +3 -3
  20. package/dist/checks/index.js +4 -79
  21. package/dist/checks/index.js.map +1 -1
  22. package/dist/checks/json-syntax-error/index.js +1 -1
  23. package/dist/checks/json-syntax-error/index.js.map +1 -1
  24. package/dist/checks/liquid-html-syntax-error/index.js +2 -2
  25. package/dist/checks/liquid-html-syntax-error/index.js.map +1 -1
  26. package/dist/checks/matching-translations/index.d.ts +2 -2
  27. package/dist/checks/matching-translations/index.js +20 -31
  28. package/dist/checks/matching-translations/index.js.map +1 -1
  29. package/dist/checks/metadata-params/index.js +6 -3
  30. package/dist/checks/metadata-params/index.js.map +1 -1
  31. package/dist/checks/missing-asset/index.js +1 -1
  32. package/dist/checks/missing-asset/index.js.map +1 -1
  33. package/dist/checks/missing-partial/index.d.ts +6 -0
  34. package/dist/checks/missing-partial/index.js +70 -0
  35. package/dist/checks/missing-partial/index.js.map +1 -0
  36. package/dist/checks/orphaned-partial/index.js +4 -4
  37. package/dist/checks/orphaned-partial/index.js.map +1 -1
  38. package/dist/checks/parser-blocking-script/index.js +10 -36
  39. package/dist/checks/parser-blocking-script/index.js.map +1 -1
  40. package/dist/checks/parser-blocking-script/suggestions.d.ts +1 -2
  41. package/dist/checks/parser-blocking-script/suggestions.js +1 -11
  42. package/dist/checks/parser-blocking-script/suggestions.js.map +1 -1
  43. package/dist/checks/reserved-doc-param-names/index.js +6 -5
  44. package/dist/checks/reserved-doc-param-names/index.js.map +1 -1
  45. package/dist/checks/translation-key-exists/index.js +1 -1
  46. package/dist/checks/translation-key-exists/index.js.map +1 -1
  47. package/dist/checks/unclosed-html-element/index.js +5 -1
  48. package/dist/checks/unclosed-html-element/index.js.map +1 -1
  49. package/dist/checks/undefined-object/index.js +7 -30
  50. package/dist/checks/undefined-object/index.js.map +1 -1
  51. package/dist/checks/unique-doc-param-names/index.js +1 -1
  52. package/dist/checks/unique-doc-param-names/index.js.map +1 -1
  53. package/dist/checks/unknown-filter/index.js +3 -3
  54. package/dist/checks/unknown-filter/index.js.map +1 -1
  55. package/dist/checks/unknown-property/index.js +1 -1
  56. package/dist/checks/unknown-property/index.js.map +1 -1
  57. package/dist/checks/unrecognized-render-partial-arguments/index.js +2 -2
  58. package/dist/checks/unrecognized-render-partial-arguments/index.js.map +1 -1
  59. package/dist/checks/unused-assign/index.js +1 -1
  60. package/dist/checks/unused-assign/index.js.map +1 -1
  61. package/dist/checks/unused-doc-param/index.js +1 -1
  62. package/dist/checks/unused-doc-param/index.js.map +1 -1
  63. package/dist/checks/utils.js +1 -1
  64. package/dist/checks/utils.js.map +1 -1
  65. package/dist/checks/valid-content-for-arguments/index.js +1 -1
  66. package/dist/checks/valid-content-for-arguments/index.js.map +1 -1
  67. package/dist/checks/valid-doc-param-types/index.js +4 -4
  68. package/dist/checks/valid-doc-param-types/index.js.map +1 -1
  69. package/dist/checks/valid-html-translation/index.d.ts +2 -2
  70. package/dist/checks/valid-html-translation/index.js +4 -4
  71. package/dist/checks/valid-html-translation/index.js.map +1 -1
  72. package/dist/checks/valid-json/index.js +1 -1
  73. package/dist/checks/valid-json/index.js.map +1 -1
  74. package/dist/checks/valid-render-partial-argument-types/index.js +2 -2
  75. package/dist/checks/valid-render-partial-argument-types/index.js.map +1 -1
  76. package/dist/checks/variable-name/index.js +1 -1
  77. package/dist/checks/variable-name/index.js.map +1 -1
  78. package/dist/context-utils.d.ts +2 -7
  79. package/dist/context-utils.js +39 -109
  80. package/dist/context-utils.js.map +1 -1
  81. package/dist/disabled-checks/index.js +4 -2
  82. package/dist/disabled-checks/index.js.map +1 -1
  83. package/dist/find-root.d.ts +7 -10
  84. package/dist/find-root.js +10 -17
  85. package/dist/find-root.js.map +1 -1
  86. package/dist/fixes/autofix.d.ts +4 -4
  87. package/dist/fixes/autofix.js +2 -2
  88. package/dist/fixes/autofix.js.map +1 -1
  89. package/dist/fixes/correctors/index.js +4 -0
  90. package/dist/fixes/correctors/index.js.map +1 -1
  91. package/dist/index.d.ts +4 -5
  92. package/dist/index.js +34 -17
  93. package/dist/index.js.map +1 -1
  94. package/dist/jsonc/parse.d.ts +1 -1
  95. package/dist/jsonc/parse.js +1 -1
  96. package/dist/liquid-doc/arguments.d.ts +7 -8
  97. package/dist/liquid-doc/arguments.js +20 -28
  98. package/dist/liquid-doc/arguments.js.map +1 -1
  99. package/dist/liquid-doc/liquidDoc.d.ts +1 -1
  100. package/dist/liquid-doc/liquidDoc.js.map +1 -1
  101. package/dist/liquid-doc/utils.d.ts +1 -1
  102. package/dist/liquid-doc/utils.js +4 -3
  103. package/dist/liquid-doc/utils.js.map +1 -1
  104. package/dist/path.d.ts +1 -0
  105. package/dist/path.js +5 -1
  106. package/dist/path.js.map +1 -1
  107. package/dist/test/MockApp.d.ts +16 -0
  108. package/dist/test/MockApp.js +16 -0
  109. package/dist/test/MockApp.js.map +1 -0
  110. package/dist/test/MockFileSystem.d.ts +3 -3
  111. package/dist/test/MockFileSystem.js +6 -6
  112. package/dist/test/MockFileSystem.js.map +1 -1
  113. package/dist/test/index.d.ts +1 -1
  114. package/dist/test/index.js +1 -1
  115. package/dist/test/index.js.map +1 -1
  116. package/dist/test/test-helper.d.ts +10 -9
  117. package/dist/test/test-helper.js +15 -106
  118. package/dist/test/test-helper.js.map +1 -1
  119. package/dist/to-source-code.d.ts +4 -3
  120. package/dist/to-source-code.js +20 -0
  121. package/dist/to-source-code.js.map +1 -1
  122. package/dist/tsconfig.tsbuildinfo +1 -1
  123. package/dist/types/platformos-liquid-docs.d.ts +128 -0
  124. package/dist/types/platformos-liquid-docs.js +3 -0
  125. package/dist/types/platformos-liquid-docs.js.map +1 -0
  126. package/dist/types/schemas/index.d.ts +0 -2
  127. package/dist/types/schemas/index.js.map +1 -1
  128. package/dist/types.d.ts +18 -67
  129. package/dist/types.js +3 -5
  130. package/dist/types.js.map +1 -1
  131. package/dist/utils/file-utils.js +1 -2
  132. package/dist/utils/file-utils.js.map +1 -1
  133. package/dist/utils/index.d.ts +0 -1
  134. package/dist/utils/index.js +0 -1
  135. package/dist/utils/index.js.map +1 -1
  136. package/dist/yaml/parse.d.ts +5 -0
  137. package/dist/yaml/parse.js +94 -0
  138. package/dist/yaml/parse.js.map +1 -0
  139. package/package.json +9 -9
  140. package/src/{AugmentedThemeDocset.spec.ts → AugmentedPlatformOSDocset.spec.ts} +47 -34
  141. package/src/AugmentedPlatformOSDocset.ts +89 -0
  142. package/src/JSONValidator.ts +1 -1
  143. package/src/checks/deprecated-filter/index.spec.ts +76 -248
  144. package/src/checks/deprecated-filter/index.ts +5 -53
  145. package/src/checks/deprecated-tag/index.spec.ts +85 -34
  146. package/src/checks/deprecated-tag/index.ts +27 -22
  147. package/src/checks/duplicate-function-arguments/index.ts +1 -1
  148. package/src/checks/duplicate-render-partial-arguments/index.ts +1 -1
  149. package/src/checks/graphql/index.ts +1 -1
  150. package/src/checks/img-width-and-height/index.ts +1 -1
  151. package/src/checks/index.ts +11 -80
  152. package/src/checks/invalid-hash-assign-target/index.spec.ts +14 -14
  153. package/src/checks/json-syntax-error/index.ts +1 -1
  154. package/src/checks/liquid-html-syntax-error/checks/InvalidBooleanExpression.spec.ts +0 -11
  155. package/src/checks/liquid-html-syntax-error/checks/InvalidLoopArguments.spec.ts +1 -2
  156. package/src/checks/liquid-html-syntax-error/index.spec.ts +1 -6
  157. package/src/checks/liquid-html-syntax-error/index.ts +2 -2
  158. package/src/checks/matching-translations/index.spec.ts +89 -346
  159. package/src/checks/matching-translations/index.ts +24 -35
  160. package/src/checks/metadata-params/index.ts +5 -7
  161. package/src/checks/missing-asset/index.ts +1 -1
  162. package/src/checks/{missing-template → missing-partial}/index.spec.ts +6 -6
  163. package/src/checks/{missing-template → missing-partial}/index.ts +6 -20
  164. package/src/checks/orphaned-partial/index.ts +3 -3
  165. package/src/checks/parser-blocking-script/index.spec.ts +0 -118
  166. package/src/checks/parser-blocking-script/index.ts +3 -33
  167. package/src/checks/parser-blocking-script/suggestions.ts +1 -28
  168. package/src/checks/translation-key-exists/index.ts +1 -1
  169. package/src/checks/unclosed-html-element/index.ts +5 -1
  170. package/src/checks/undefined-object/index.spec.ts +3 -109
  171. package/src/checks/undefined-object/index.ts +8 -33
  172. package/src/checks/unique-doc-param-names/index.ts +1 -1
  173. package/src/checks/unknown-filter/index.spec.ts +2 -2
  174. package/src/checks/unknown-filter/index.ts +3 -3
  175. package/src/checks/unknown-property/index.ts +1 -1
  176. package/src/checks/unrecognized-render-partial-arguments/index.spec.ts +5 -5
  177. package/src/checks/unrecognized-render-partial-arguments/index.ts +2 -5
  178. package/src/checks/unused-assign/index.spec.ts +0 -30
  179. package/src/checks/unused-assign/index.ts +1 -1
  180. package/src/checks/unused-doc-param/index.ts +1 -1
  181. package/src/checks/utils.ts +1 -1
  182. package/src/checks/valid-doc-param-types/index.ts +4 -4
  183. package/src/checks/valid-html-translation/index.spec.ts +42 -32
  184. package/src/checks/valid-html-translation/index.ts +7 -7
  185. package/src/checks/valid-json/index.ts +1 -1
  186. package/src/checks/valid-render-partial-argument-types/index.ts +2 -5
  187. package/src/checks/variable-name/index.ts +1 -1
  188. package/src/context-utils.spec.ts +49 -77
  189. package/src/context-utils.ts +39 -128
  190. package/src/disabled-checks/index.spec.ts +35 -0
  191. package/src/disabled-checks/index.ts +4 -2
  192. package/src/find-root.ts +12 -22
  193. package/src/fixes/autofix.spec.ts +2 -2
  194. package/src/fixes/autofix.ts +4 -4
  195. package/src/fixes/correctors/index.ts +4 -0
  196. package/src/ignore.spec.ts +0 -1
  197. package/src/index.ts +33 -21
  198. package/src/jsonc/parse.ts +1 -1
  199. package/src/liquid-doc/arguments.spec.ts +19 -45
  200. package/src/liquid-doc/arguments.ts +26 -39
  201. package/src/liquid-doc/liquidDoc.ts +1 -2
  202. package/src/liquid-doc/utils.ts +4 -3
  203. package/src/path.ts +1 -0
  204. package/src/test/{MockTheme.ts → MockApp.ts} +1 -1
  205. package/src/test/MockFileSystem.ts +9 -6
  206. package/src/test/index.ts +1 -1
  207. package/src/test/test-helper.ts +29 -127
  208. package/src/to-source-code.ts +20 -1
  209. package/src/types/{theme-liquid-docs.ts → platformos-liquid-docs.ts} +8 -13
  210. package/src/types/schemas/index.ts +0 -2
  211. package/src/types.ts +21 -92
  212. package/src/utils/file-utils.ts +0 -1
  213. package/src/utils/index.ts +0 -1
  214. package/src/yaml/parse.ts +111 -0
  215. package/src/AugmentedThemeDocset.ts +0 -137
  216. package/src/checks/app-block-missing-schema/index.spec.ts +0 -121
  217. package/src/checks/app-block-missing-schema/index.ts +0 -46
  218. package/src/checks/app-block-valid-tags/index.spec.ts +0 -96
  219. package/src/checks/app-block-valid-tags/index.ts +0 -54
  220. package/src/checks/asset-preload/index.spec.ts +0 -78
  221. package/src/checks/asset-preload/index.ts +0 -65
  222. package/src/checks/asset-size-app-block-css/index.spec.ts +0 -88
  223. package/src/checks/asset-size-app-block-css/index.ts +0 -78
  224. package/src/checks/asset-size-app-block-javascript/index.spec.ts +0 -66
  225. package/src/checks/asset-size-app-block-javascript/index.ts +0 -78
  226. package/src/checks/asset-size-css/index.spec.ts +0 -166
  227. package/src/checks/asset-size-css/index.ts +0 -160
  228. package/src/checks/asset-size-javascript/index.spec.ts +0 -184
  229. package/src/checks/asset-size-javascript/index.ts +0 -144
  230. package/src/checks/block-id-usage/index.spec.ts +0 -76
  231. package/src/checks/block-id-usage/index.ts +0 -72
  232. package/src/checks/cdn-preconnect/index.spec.ts +0 -40
  233. package/src/checks/cdn-preconnect/index.ts +0 -43
  234. package/src/checks/content-for-header-modification/index.spec.ts +0 -65
  235. package/src/checks/content-for-header-modification/index.ts +0 -72
  236. package/src/checks/deprecate-bgsizes/index.spec.ts +0 -41
  237. package/src/checks/deprecate-bgsizes/index.ts +0 -49
  238. package/src/checks/deprecate-lazysizes/index.spec.ts +0 -26
  239. package/src/checks/deprecate-lazysizes/index.ts +0 -58
  240. package/src/checks/deprecated-filter/fixes.ts +0 -264
  241. package/src/checks/deprecated-fonts-on-sections-and-blocks/deprecated-fonts-data.ts +0 -1343
  242. package/src/checks/deprecated-fonts-on-sections-and-blocks/index.spec.ts +0 -613
  243. package/src/checks/deprecated-fonts-on-sections-and-blocks/index.ts +0 -284
  244. package/src/checks/deprecated-fonts-on-settings-schema/index.spec.ts +0 -102
  245. package/src/checks/deprecated-fonts-on-settings-schema/index.ts +0 -66
  246. package/src/checks/duplicate-content-for-arguments/index.spec.ts +0 -98
  247. package/src/checks/duplicate-content-for-arguments/index.ts +0 -43
  248. package/src/checks/empty-block-content/index.spec.ts +0 -117
  249. package/src/checks/empty-block-content/index.ts +0 -60
  250. package/src/checks/hardcoded-routes/index.spec.ts +0 -58
  251. package/src/checks/hardcoded-routes/index.ts +0 -100
  252. package/src/checks/json-missing-block/index.spec.ts +0 -435
  253. package/src/checks/json-missing-block/index.ts +0 -56
  254. package/src/checks/json-missing-block/missing-block-utils.ts +0 -147
  255. package/src/checks/liquid-free-settings/index.spec.ts +0 -180
  256. package/src/checks/liquid-free-settings/index.ts +0 -79
  257. package/src/checks/missing-content-for-arguments/index.spec.ts +0 -144
  258. package/src/checks/missing-content-for-arguments/index.ts +0 -46
  259. package/src/checks/pagination-size/index.spec.ts +0 -158
  260. package/src/checks/pagination-size/index.ts +0 -104
  261. package/src/checks/remote-asset/index.spec.ts +0 -280
  262. package/src/checks/remote-asset/index.ts +0 -238
  263. package/src/checks/reserved-doc-param-names/index.spec.ts +0 -62
  264. package/src/checks/reserved-doc-param-names/index.ts +0 -57
  265. package/src/checks/schema-presets-block-order/index.spec.ts +0 -344
  266. package/src/checks/schema-presets-block-order/index.ts +0 -154
  267. package/src/checks/schema-presets-static-blocks/index.spec.ts +0 -145
  268. package/src/checks/schema-presets-static-blocks/index.ts +0 -126
  269. package/src/checks/static-stylesheet-and-javascript-tags/index.spec.ts +0 -257
  270. package/src/checks/static-stylesheet-and-javascript-tags/index.ts +0 -48
  271. package/src/checks/unique-settings-id/index.spec.ts +0 -24
  272. package/src/checks/unique-settings-id/index.ts +0 -84
  273. package/src/checks/unique-settings-id/test-data.ts +0 -1191
  274. package/src/checks/unique-static-block-id/index.spec.ts +0 -55
  275. package/src/checks/unique-static-block-id/index.ts +0 -60
  276. package/src/checks/unrecognized-content-for-arguments/index.spec.ts +0 -145
  277. package/src/checks/unrecognized-content-for-arguments/index.ts +0 -55
  278. package/src/checks/valid-block-target/index.spec.ts +0 -1396
  279. package/src/checks/valid-block-target/index.ts +0 -142
  280. package/src/checks/valid-content-for-argument-types/index.spec.ts +0 -382
  281. package/src/checks/valid-content-for-argument-types/index.ts +0 -42
  282. package/src/checks/valid-content-for-arguments/index.spec.ts +0 -107
  283. package/src/checks/valid-content-for-arguments/index.ts +0 -98
  284. package/src/checks/valid-local-blocks/index.spec.ts +0 -286
  285. package/src/checks/valid-local-blocks/index.ts +0 -100
  286. package/src/checks/valid-local-blocks/valid-block-utils.ts +0 -97
  287. package/src/checks/valid-schema/index.spec.ts +0 -174
  288. package/src/checks/valid-schema/index.ts +0 -41
  289. package/src/checks/valid-schema-name/index.spec.ts +0 -112
  290. package/src/checks/valid-schema-name/index.ts +0 -75
  291. package/src/checks/valid-settings-key/index.spec.ts +0 -321
  292. package/src/checks/valid-settings-key/index.ts +0 -144
  293. package/src/checks/valid-static-block-type/index.spec.ts +0 -38
  294. package/src/checks/valid-static-block-type/index.ts +0 -58
  295. package/src/checks/valid-visible-if/index.spec.ts +0 -619
  296. package/src/checks/valid-visible-if/index.ts +0 -184
  297. package/src/checks/valid-visible-if/visible-if-utils.ts +0 -158
  298. package/src/tags/content-for.ts +0 -25
  299. package/src/to-schema.ts +0 -231
  300. package/src/types/schemas/section.ts +0 -86
  301. package/src/types/schemas/theme-block.ts +0 -34
  302. package/src/types/theme-schemas.ts +0 -80
  303. package/src/utils/block.ts +0 -300
  304. package/src/utils/markup.ts +0 -10
@@ -1,12 +1,12 @@
1
1
  import { describe, beforeEach, it, expect } from 'vitest';
2
- import { AugmentedThemeDocset } from './AugmentedThemeDocset';
3
- import { ThemeDocset } from './types';
2
+ import { AugmentedPlatformOSDocset } from './AugmentedPlatformOSDocset';
3
+ import { PlatformOSDocset } from './types';
4
4
 
5
- describe('Module: AugmentedThemeDocset', async () => {
6
- let themeDocset: ThemeDocset;
5
+ describe('Module: AugmentedPlatformOSDocset', async () => {
6
+ let platformosDocset: PlatformOSDocset;
7
7
 
8
8
  beforeEach(async () => {
9
- themeDocset = new AugmentedThemeDocset({
9
+ platformosDocset = new AugmentedPlatformOSDocset({
10
10
  graphQL: async () => null,
11
11
  filters: async () => [],
12
12
  objects: async () => [
@@ -51,25 +51,24 @@ describe('Module: AugmentedThemeDocset', async () => {
51
51
  ],
52
52
  liquidDrops: async () => [],
53
53
  tags: async () => [],
54
- systemTranslations: async () => ({}),
55
54
  });
56
55
  });
57
56
 
58
57
  describe('filters', async () => {
59
58
  it('should return filters with undocumented filters', async () => {
60
- const filters = await themeDocset.filters();
59
+ const filters = await platformosDocset.filters();
61
60
 
62
- expect(filters).to.have.length.greaterThanOrEqual(30);
61
+ expect(filters).to.have.length.greaterThanOrEqual(10);
63
62
  });
64
63
 
65
64
  it('should return valid filter entries', async () => {
66
- const filters = await themeDocset.filters();
65
+ const filters = await platformosDocset.filters();
67
66
 
68
67
  expect(filters).to.deep.include({ name: 'h' });
69
68
  });
70
69
 
71
70
  it('should expand aliases from filter entries', async () => {
72
- const docset = new AugmentedThemeDocset({
71
+ const docset = new AugmentedPlatformOSDocset({
73
72
  graphQL: async () => null,
74
73
  filters: async () => [
75
74
  {
@@ -82,7 +81,6 @@ describe('Module: AugmentedThemeDocset', async () => {
82
81
  objects: async () => [],
83
82
  liquidDrops: async () => [],
84
83
  tags: async () => [],
85
- systemTranslations: async () => ({}),
86
84
  });
87
85
 
88
86
  const filters = await docset.filters();
@@ -93,7 +91,7 @@ describe('Module: AugmentedThemeDocset', async () => {
93
91
  });
94
92
 
95
93
  it('should copy all properties from base filter to alias entry', async () => {
96
- const docset = new AugmentedThemeDocset({
94
+ const docset = new AugmentedPlatformOSDocset({
97
95
  graphQL: async () => null,
98
96
  filters: async () => [
99
97
  {
@@ -115,7 +113,6 @@ describe('Module: AugmentedThemeDocset', async () => {
115
113
  objects: async () => [],
116
114
  liquidDrops: async () => [],
117
115
  tags: async () => [],
118
- systemTranslations: async () => ({}),
119
116
  });
120
117
 
121
118
  const filters = await docset.filters();
@@ -128,7 +125,7 @@ describe('Module: AugmentedThemeDocset', async () => {
128
125
  });
129
126
 
130
127
  it('should expand multiple aliases for a single filter', async () => {
131
- const docset = new AugmentedThemeDocset({
128
+ const docset = new AugmentedPlatformOSDocset({
132
129
  graphQL: async () => null,
133
130
  filters: async () => [
134
131
  {
@@ -140,7 +137,6 @@ describe('Module: AugmentedThemeDocset', async () => {
140
137
  objects: async () => [],
141
138
  liquidDrops: async () => [],
142
139
  tags: async () => [],
143
- systemTranslations: async () => ({}),
144
140
  });
145
141
 
146
142
  const filters = await docset.filters();
@@ -152,7 +148,7 @@ describe('Module: AugmentedThemeDocset', async () => {
152
148
  });
153
149
 
154
150
  it('should not add aliases for filters without aliases', async () => {
155
- const docset = new AugmentedThemeDocset({
151
+ const docset = new AugmentedPlatformOSDocset({
156
152
  graphQL: async () => null,
157
153
  filters: async () => [
158
154
  { name: 'upcase', summary: 'Uppercases a string' },
@@ -161,7 +157,6 @@ describe('Module: AugmentedThemeDocset', async () => {
161
157
  objects: async () => [],
162
158
  liquidDrops: async () => [],
163
159
  tags: async () => [],
164
- systemTranslations: async () => ({}),
165
160
  });
166
161
 
167
162
  const filters = await docset.filters();
@@ -169,39 +164,57 @@ describe('Module: AugmentedThemeDocset', async () => {
169
164
 
170
165
  expect(officialNames).toHaveLength(2);
171
166
  });
167
+
168
+ it('should normalize filters with deprecated:false but deprecation_reason:"true" to deprecated:true', async () => {
169
+ const docset = new AugmentedPlatformOSDocset({
170
+ graphQL: async () => null,
171
+ filters: async () => [
172
+ { name: 'asset_path', deprecated: false, deprecation_reason: 'true' },
173
+ { name: 'sha1', deprecated: false, deprecation_reason: 'true' },
174
+ { name: 'active_filter', deprecated: false, deprecation_reason: 'false' },
175
+ ],
176
+ objects: async () => [],
177
+ liquidDrops: async () => [],
178
+ tags: async () => [],
179
+ });
180
+
181
+ const filters = await docset.filters();
182
+ const assetPath = filters.find((f) => f.name === 'asset_path');
183
+ const sha1 = filters.find((f) => f.name === 'sha1');
184
+ const active = filters.find((f) => f.name === 'active_filter');
185
+
186
+ expect(assetPath?.deprecated).toBe(true);
187
+ expect(assetPath?.deprecation_reason).toBeUndefined();
188
+ expect(sha1?.deprecated).toBe(true);
189
+ expect(sha1?.deprecation_reason).toBeUndefined();
190
+ expect(active?.deprecated).toBeFalsy();
191
+ });
172
192
  });
173
193
 
174
194
  describe('objects', async () => {
175
- it('should return objects with undocumented objects', async () => {
176
- const objects = await themeDocset.objects();
195
+ it('should return objects from the official docset', async () => {
196
+ const objects = await platformosDocset.objects();
177
197
 
178
- expect(objects).to.have.length.greaterThanOrEqual(15);
198
+ expect(objects).to.have.length.greaterThanOrEqual(4);
179
199
  });
180
200
 
181
201
  it('should return valid object entries', async () => {
182
- const objects = await themeDocset.objects();
202
+ const objects = await platformosDocset.objects();
183
203
 
184
- expect(objects).to.deep.include({ name: 'customer_address' });
185
204
  expect(objects).to.deep.include({
186
- name: 'locale',
205
+ name: 'test-object',
187
206
  access: {
188
207
  global: false,
189
208
  parents: [],
190
209
  template: [],
191
210
  },
192
- return_type: [
193
- {
194
- type: 'string',
195
- name: '',
196
- },
197
- ],
198
211
  });
199
212
  });
200
213
  });
201
214
 
202
215
  describe('liquidDrops', async () => {
203
216
  it('should return non-deprecated objects', async () => {
204
- const objects = await themeDocset.liquidDrops();
217
+ const objects = await platformosDocset.liquidDrops();
205
218
 
206
219
  expect(objects).to.have.lengthOf(2);
207
220
  expect(objects).to.deep.include({
@@ -215,7 +228,7 @@ describe('Module: AugmentedThemeDocset', async () => {
215
228
  });
216
229
 
217
230
  it("should return objects that aren't exclusively global", async () => {
218
- const objects = await themeDocset.liquidDrops();
231
+ const objects = await platformosDocset.liquidDrops();
219
232
 
220
233
  expect(objects).to.have.lengthOf(2);
221
234
  expect(objects).to.deep.include({
@@ -236,13 +249,13 @@ describe('Module: AugmentedThemeDocset', async () => {
236
249
 
237
250
  describe('tags', async () => {
238
251
  it('should return tags with undocumented tags', async () => {
239
- const tags = await themeDocset.tags();
252
+ const tags = await platformosDocset.tags();
240
253
 
241
- expect(tags).have.length.greaterThanOrEqual(4);
254
+ expect(tags).have.length.greaterThanOrEqual(3);
242
255
  });
243
256
 
244
257
  it('should return valid tag entries', async () => {
245
- const tags = await themeDocset.tags();
258
+ const tags = await platformosDocset.tags();
246
259
 
247
260
  expect(tags).to.deep.include({ name: 'elsif' });
248
261
  });
@@ -0,0 +1,89 @@
1
+ import { FilterEntry, ObjectEntry, TagEntry, PlatformOSDocset } from './types';
2
+ import { memo } from './utils';
3
+
4
+ const toFilterEntry = (name: string): FilterEntry => ({ name });
5
+
6
+ const expandAliases = (entries: FilterEntry[]): FilterEntry[] => {
7
+ return entries.flatMap((entry) => {
8
+ const aliases: string[] = (entry as any).aliases ?? [];
9
+ return aliases.map((alias) => ({ ...entry, name: alias }));
10
+ });
11
+ };
12
+
13
+ /**
14
+ * The platformOS API has a data inconsistency where some deprecated filters
15
+ * have `deprecated: false` but `deprecation_reason: "true"` (the string).
16
+ * Normalize these to have `deprecated: true` with no deprecation reason message.
17
+ */
18
+ const normalizeDeprecation = (entry: FilterEntry): FilterEntry => {
19
+ if (!entry.deprecated && entry.deprecation_reason === 'true') {
20
+ return { ...entry, deprecated: true, deprecation_reason: undefined };
21
+ }
22
+ return entry;
23
+ };
24
+
25
+ /**
26
+ * Filters that are valid in platformOS but not yet in the official docs.
27
+ */
28
+ const undocumentedFilters = [
29
+ 'debug',
30
+ 'distance_from',
31
+ 'encode_url_component',
32
+ 'excerpt',
33
+ 'format_code',
34
+ 'h',
35
+ 'handle_from',
36
+ 'pad_spaces',
37
+ 'paragraphize',
38
+ 'sentence',
39
+ 'unit',
40
+ 'weight',
41
+ ];
42
+
43
+ const toTagEntry = (name: string): TagEntry => ({ name });
44
+
45
+ /**
46
+ * Tags that are valid in platformOS Liquid but not yet in the official docs.
47
+ */
48
+ const undocumentedTags = ['elsif', 'ifchanged', 'when'];
49
+
50
+ export class AugmentedPlatformOSDocset implements PlatformOSDocset {
51
+ constructor(private platformosDocset: PlatformOSDocset) {}
52
+ graphQL = memo(async (): Promise<string | null> => {
53
+ return await this.platformosDocset.graphQL();
54
+ });
55
+
56
+ public isAugmented = true;
57
+
58
+ filters = memo(async (): Promise<FilterEntry[]> => {
59
+ const officialFilters = (await this.platformosDocset.filters()).map(normalizeDeprecation);
60
+ return [
61
+ ...officialFilters,
62
+ ...expandAliases(officialFilters),
63
+ ...undocumentedFilters.map(toFilterEntry),
64
+ ];
65
+ });
66
+
67
+ objects = memo(async (): Promise<ObjectEntry[]> => {
68
+ return await this.platformosDocset.objects();
69
+ });
70
+
71
+ liquidDrops = memo(async (): Promise<ObjectEntry[]> => {
72
+ return (await this.platformosDocset.objects()).filter((obj) => {
73
+ if (!obj.access) {
74
+ return true;
75
+ }
76
+
77
+ if (obj.deprecated) {
78
+ return false;
79
+ }
80
+
81
+ // objects that are accessible outside Global context
82
+ return !obj.access.global || (obj.access.global && obj.access.parents.length > 0);
83
+ });
84
+ });
85
+
86
+ tags = memo(async (): Promise<TagEntry[]> => {
87
+ return [...(await this.platformosDocset.tags()), ...undocumentedTags.map(toTagEntry)];
88
+ });
89
+ }
@@ -11,7 +11,7 @@ export class JSONValidator {
11
11
  config: Config,
12
12
  ): Promise<JSONValidator | undefined> {
13
13
  if (!jsonValidationSet) return;
14
- return new JSONValidator(await jsonValidationSet.schemas(config.context));
14
+ return new JSONValidator(await jsonValidationSet.schemas());
15
15
  }
16
16
 
17
17
  constructor(schemas: SchemaDefinition[]) {
@@ -1,274 +1,102 @@
1
1
  import { expect, describe, it } from 'vitest';
2
- import { highlightedOffenses, applySuggestions, runLiquidCheck, applyFix } from '../../test';
2
+ import { highlightedOffenses, runLiquidCheck } from '../../test';
3
3
  import { DeprecatedFilter } from './index';
4
- import { Offense } from '../../types';
4
+
5
+ const mockDependencies = {
6
+ platformosDocset: {
7
+ async graphQL() {
8
+ return null;
9
+ },
10
+ async filters() {
11
+ return [
12
+ {
13
+ name: 'old_filter',
14
+ deprecated: true,
15
+ deprecation_reason: '`old_filter` has been replaced by [`new_filter`](/docs/...).',
16
+ },
17
+ {
18
+ name: 'deprecated_no_replacement',
19
+ deprecated: true,
20
+ },
21
+ {
22
+ name: 'new_filter',
23
+ },
24
+ {
25
+ name: 'active_filter',
26
+ },
27
+ ];
28
+ },
29
+ async objects() {
30
+ return [];
31
+ },
32
+ async liquidDrops() {
33
+ return [];
34
+ },
35
+ async tags() {
36
+ return [];
37
+ },
38
+ },
39
+ };
5
40
 
6
41
  describe('Module: DeprecatedFilter', () => {
7
42
  it('should report an offense when a deprecated filter is used', async () => {
8
43
  const sourceCode = `
9
- {{ '#EA5AB9' | hex_to_rgba }}
10
- {{ '#EA5AB9' | hex_to_rgba: 0.5 }}
44
+ {{ value | old_filter }}
45
+ {{ value | old_filter: 'arg' }}
11
46
  `;
12
47
 
13
- const offenses = await runLiquidCheck(DeprecatedFilter, sourceCode);
48
+ const offenses = await runLiquidCheck(
49
+ DeprecatedFilter,
50
+ sourceCode,
51
+ 'file.liquid',
52
+ mockDependencies,
53
+ );
14
54
  expect(offenses.map((e) => e.message)).toEqual([
15
- "Deprecated filter 'hex_to_rgba', consider using 'color_to_rgb'.",
16
- "Deprecated filter 'hex_to_rgba', consider using 'color_to_rgb'.",
55
+ "Deprecated filter 'old_filter', consider using 'new_filter'.",
56
+ "Deprecated filter 'old_filter', consider using 'new_filter'.",
17
57
  ]);
18
58
 
19
59
  const highlights = highlightedOffenses({ 'file.liquid': sourceCode }, offenses);
20
- expect(highlights).toEqual(['| hex_to_rgba', '| hex_to_rgba: 0.5']);
60
+ expect(highlights).toEqual(['| old_filter', "| old_filter: 'arg'"]);
21
61
  });
22
62
 
23
63
  it('should not report an offense when a non-deprecated filter is used', async () => {
24
64
  const sourceCode = `
25
- {{ '#EA5AB9' | color_to_rgb }}
26
- {{ '#EA5AB9' | color_to_rgb | color_modify: 'alpha', 0.5 }}
65
+ {{ value | active_filter }}
66
+ {{ value | new_filter }}
27
67
  `;
28
68
 
29
- const offenses = await runLiquidCheck(DeprecatedFilter, sourceCode);
30
-
69
+ const offenses = await runLiquidCheck(
70
+ DeprecatedFilter,
71
+ sourceCode,
72
+ 'file.liquid',
73
+ mockDependencies,
74
+ );
31
75
  expect(offenses).toHaveLength(0);
32
76
  });
33
77
 
34
- it("should suggest a fix to replace the deprecated 'hex_to_rgba' filter", async () => {
35
- const sourceCode = '{{ "#EA5AB9" | hex_to_rgba }}';
36
-
37
- const offenses = await runLiquidCheck(DeprecatedFilter, sourceCode);
38
- const fixedCode = applyFix(sourceCode, offenses[0]);
39
-
40
- expect(fixedCode).toEqual('{{ "#EA5AB9" | color_to_rgb }}');
78
+ it('should report a message without replacement when no alternative exists', async () => {
79
+ const sourceCode = `{{ value | deprecated_no_replacement }}`;
80
+
81
+ const offenses = await runLiquidCheck(
82
+ DeprecatedFilter,
83
+ sourceCode,
84
+ 'file.liquid',
85
+ mockDependencies,
86
+ );
87
+ expect(offenses).toHaveLength(1);
88
+ expect(offenses[0].message).toEqual("Deprecated filter 'deprecated_no_replacement'.");
41
89
  });
42
90
 
43
- it("should suggest a fix to replace the deprecated 'hex_to_rgba' filter when an alpha value is passed", async () => {
44
- const sourceCode = '{{ "#EA5AB9" | hex_to_rgba: 0.5 }}';
45
-
46
- const offenses = await runLiquidCheck(DeprecatedFilter, sourceCode);
47
- const fixedCode = applyFix(sourceCode, offenses[0]);
91
+ it('should report multiple offenses for multiple deprecated filter usages', async () => {
92
+ const sourceCode = `{{ a | old_filter }} {{ b | deprecated_no_replacement }}`;
48
93
 
49
- expect(fixedCode).toEqual(`{{ "#EA5AB9" | color_to_rgb | color_modify: 'alpha', 0.5 }}`);
50
- });
51
-
52
- it("should suggest a fix to replace the deprecated 'img_url' filter", async () => {
53
- const sourceCode = `
54
- {{ product.featured_image | img_url: '200x', scale: 2, crop: 'center' }}
55
- {{ product.featured_image | img_url: '200x', scale: 2 }}
56
- {{ product.featured_image | img_url: '200x' }}
57
- {{ product.featured_image | img_url: '200x300' }}
58
- {{ product.featured_image | img_url: 'x300' }}
59
- {{ product.featured_image | img_url }}
60
- {{ product.featured_image
61
- | img_url: '200x'
62
- }}
63
- {{ product.featured_image
64
- | img_url: '200x',
65
- format: format
66
- | image_tag
67
- }}
68
- {{product.featured_image | img_url: '200x'}}
69
- {{-product.featured_image | img_url: '200x'-}}
70
- {% assign url = product.featured_image | img_url: '200x' %}
71
- {% assign url =
72
- product.featured_image | img_url: '200x'
73
- %}
74
- {{ product.featured_image | img_url: 'master' }}
75
- {{ product.featured_image | img_url: '4000x', scale: 2 }}
76
-
77
- // not supported:
78
- {{ product.featured_image | img_url: variable }}
79
- {{ product.featured_image | img_url: '200x', scale: variable }}
80
- `;
81
-
82
- const offenses = await runLiquidCheck(DeprecatedFilter, sourceCode);
83
- const fixedCode = fixSourceCode(sourceCode, offenses);
84
-
85
- const expected = `
86
- {{ product.featured_image | image_url: width: 400, crop: 'center' }}
87
- {{ product.featured_image | image_url: width: 400 }}
88
- {{ product.featured_image | image_url: width: 200 }}
89
- {{ product.featured_image | image_url: width: 200, height: 300 }}
90
- {{ product.featured_image | image_url: height: 300 }}
91
- {{ product.featured_image | image_url: width: 100, height: 100 }}
92
- {{ product.featured_image
93
- | image_url: width: 200
94
- }}
95
- {{ product.featured_image
96
- | image_url: width: 200, format: format
97
- | image_tag
98
- }}
99
- {{product.featured_image | image_url: width: 200}}
100
- {{-product.featured_image | image_url: width: 200-}}
101
- {% assign url = product.featured_image | image_url: width: 200 %}
102
- {% assign url =
103
- product.featured_image | image_url: width: 200
104
- %}
105
- {{ product.featured_image | image_url: width: 100 }}
106
- {{ product.featured_image | image_url: width: 5760 }}
107
-
108
- // not supported:
109
- {{ product.featured_image | img_url: variable }}
110
- {{ product.featured_image | img_url: '200x', scale: variable }}
111
- `;
112
-
113
- expect(fixedCode).toEqual(expected);
114
- });
115
-
116
- it("should suggest a fix to replace the deprecated 'img_url' filter with named sizes", async () => {
117
- const sourceCode = `
118
- {{ product.featured_image | img_url: 'pico', scale: 2, crop: 'center' }}
119
- {{ product.featured_image | img_url: 'pico' }}
120
-
121
- {{ product.featured_image | img_url: 'icon', scale: 2, crop: 'center' }}
122
- {{ product.featured_image | img_url: 'icon' }}
123
-
124
- {{ product.featured_image | img_url: 'thumb', scale: 2, crop: 'center' }}
125
- {{ product.featured_image | img_url: 'thumb' }}
126
-
127
- {{ product.featured_image | img_url: 'small', scale: 2, crop: 'center' }}
128
- {{ product.featured_image | img_url: 'small' }}
129
-
130
- {{ product.featured_image | img_url: 'compact', scale: 2, crop: 'center' }}
131
- {{ product.featured_image | img_url: 'compact' }}
132
-
133
- {{ product.featured_image | img_url: 'medium', scale: 2, crop: 'center' }}
134
- {{ product.featured_image | img_url: 'medium' }}
135
-
136
- {{ product.featured_image | img_url: 'large', scale: 2, crop: 'center' }}
137
- {{ product.featured_image | img_url: 'large' }}
138
-
139
- {{ product.featured_image | img_url: 'grande', scale: 2, crop: 'center' }}
140
- {{ product.featured_image | img_url: 'grande' }}
141
-
142
- {{ product.featured_image | img_url: 'original', scale: 2, crop: 'center' }}
143
- {{ product.featured_image | img_url: 'original' }}
144
-
145
- {{ product.featured_image | img_url: 'master', scale: 2, crop: 'center' }}
146
- {{ product.featured_image | img_url: 'master' }}
147
- `;
148
-
149
- const offenses = await runLiquidCheck(DeprecatedFilter, sourceCode);
150
- const fixedCode = fixSourceCode(sourceCode, offenses);
151
-
152
- const expected = `
153
- {{ product.featured_image | image_url: width: 32, height: 32, crop: 'center' }}
154
- {{ product.featured_image | image_url: width: 16, height: 16 }}
155
-
156
- {{ product.featured_image | image_url: width: 64, height: 64, crop: 'center' }}
157
- {{ product.featured_image | image_url: width: 32, height: 32 }}
158
-
159
- {{ product.featured_image | image_url: width: 100, height: 100, crop: 'center' }}
160
- {{ product.featured_image | image_url: width: 50, height: 50 }}
161
-
162
- {{ product.featured_image | image_url: width: 200, height: 200, crop: 'center' }}
163
- {{ product.featured_image | image_url: width: 100, height: 100 }}
164
-
165
- {{ product.featured_image | image_url: width: 320, height: 320, crop: 'center' }}
166
- {{ product.featured_image | image_url: width: 160, height: 160 }}
167
-
168
- {{ product.featured_image | image_url: width: 480, height: 480, crop: 'center' }}
169
- {{ product.featured_image | image_url: width: 240, height: 240 }}
170
-
171
- {{ product.featured_image | image_url: width: 960, height: 960, crop: 'center' }}
172
- {{ product.featured_image | image_url: width: 480, height: 480 }}
173
-
174
- {{ product.featured_image | image_url: width: 1200, height: 1200, crop: 'center' }}
175
- {{ product.featured_image | image_url: width: 600, height: 600 }}
176
-
177
- {{ product.featured_image | image_url: width: 2048, height: 2048, crop: 'center' }}
178
- {{ product.featured_image | image_url: width: 1024, height: 1024 }}
179
-
180
- {{ product.featured_image | image_url: width: 100, crop: 'center' }}
181
- {{ product.featured_image | image_url: width: 100 }}
182
- `;
183
-
184
- expect(fixedCode).toEqual(expected);
185
- });
186
-
187
- it("should suggest a fix to replace the deprecated 'article_img_url' filter", async () => {
188
- const sourceCode = '{{ article.image | article_img_url }}';
189
-
190
- const offenses = await runLiquidCheck(DeprecatedFilter, sourceCode);
191
- const suggestions = applySuggestions(sourceCode, offenses[0]);
192
-
193
- expect(suggestions).toEqual(['{{ article.image | image_url: width: 100, height: 100 }}']);
194
- });
195
-
196
- it("should suggest a fix to replace the deprecated 'article_img_url' filter with named sizes", async () => {
197
- const sourceCode = '{{ article.image | article_img_url: "grande" }}';
198
-
199
- const offenses = await runLiquidCheck(DeprecatedFilter, sourceCode);
200
- const suggestions = applySuggestions(sourceCode, offenses[0]);
201
-
202
- expect(suggestions).toEqual(['{{ article.image | image_url: width: 600, height: 600 }}']);
203
- });
204
-
205
- it("should suggest a fix to replace the deprecated 'collection_img_url' filter", async () => {
206
- const sourceCode = '{{ collection.image | collection_img_url }}';
207
-
208
- const offenses = await runLiquidCheck(DeprecatedFilter, sourceCode);
209
- const suggestions = applySuggestions(sourceCode, offenses[0]);
210
-
211
- expect(suggestions).toEqual(['{{ collection.image | image_url: width: 100, height: 100 }}']);
212
- });
213
-
214
- it("should suggest a fix to replace the deprecated 'collection_img_url' filter with named sizes", async () => {
215
- const sourceCode = '{{ collection.image | collection_img_url: "grande" }}';
216
-
217
- const offenses = await runLiquidCheck(DeprecatedFilter, sourceCode);
218
- const suggestions = applySuggestions(sourceCode, offenses[0]);
219
-
220
- expect(suggestions).toEqual(['{{ collection.image | image_url: width: 600, height: 600 }}']);
221
- });
222
-
223
- it("should suggest a fix to replace the deprecated 'product_img_url' filter", async () => {
224
- const sourceCode = '{{ p.featured_image | product_img_url }}';
225
-
226
- const offenses = await runLiquidCheck(DeprecatedFilter, sourceCode);
227
- const suggestions = applySuggestions(sourceCode, offenses[0]);
228
-
229
- expect(suggestions).toEqual(['{{ p.featured_image | image_url: width: 100, height: 100 }}']);
230
- });
231
-
232
- it("should suggest a fix to replace the deprecated 'product_img_url' filter with named sizes", async () => {
233
- const sourceCode = '{{ p.featured_image | product_img_url: "grande" }}';
234
-
235
- const offenses = await runLiquidCheck(DeprecatedFilter, sourceCode);
236
- const suggestions = applySuggestions(sourceCode, offenses[0]);
237
-
238
- expect(suggestions).toEqual(['{{ p.featured_image | image_url: width: 600, height: 600 }}']);
239
- });
240
-
241
- it("should suggest a fix to replace the deprecated 'img_tag' filter", async () => {
242
- const sourceCode = `
243
- {{ product | img_tag }}
244
- {{ product | img_tag: 'image alt text' }}
245
- {{ product | img_tag: 'image alt text', 'my-css-class' }}
246
- {{ product | img_tag: 'image alt text', 'my-css-class', '200x300' }}
247
- {{ product | img_tag: 'image alt text', 'my-css-class', 'grande' }}
248
- `;
249
-
250
- const offenses = await runLiquidCheck(DeprecatedFilter, sourceCode);
251
- const fixedCode = fixSourceCode(sourceCode, offenses);
252
-
253
- const expected = `
254
- {{ product | image_url: width: 100 | image_tag }}
255
- {{ product | image_url: width: 100 | image_tag: alt: 'image alt text' }}
256
- {{ product | image_url: width: 100 | image_tag: alt: 'image alt text', class: 'my-css-class' }}
257
- {{ product | image_url: width: 200, height: 300 | image_tag: width: 200, height: 300, alt: 'image alt text', class: 'my-css-class' }}
258
- {{ product | image_url: width: 600, height: 600 | image_tag: width: 600, height: 600, alt: 'image alt text', class: 'my-css-class' }}
259
- `;
260
-
261
- expect(fixedCode).toEqual(expected);
94
+ const offenses = await runLiquidCheck(
95
+ DeprecatedFilter,
96
+ sourceCode,
97
+ 'file.liquid',
98
+ mockDependencies,
99
+ );
100
+ expect(offenses).toHaveLength(2);
262
101
  });
263
102
  });
264
-
265
- function fixSourceCode(source: string, offenses: Offense[]) {
266
- offenses
267
- .reverse()
268
- .filter((offense) => offense.suggest)
269
- .forEach((offense) => {
270
- source = applySuggestions(source, offense)?.join('') || source;
271
- });
272
-
273
- return source;
274
- }