@ttsc/lint 0.13.0 → 0.14.0-dev.20260528

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 (467) hide show
  1. package/README.md +948 -69
  2. package/lib/defaultFormat.d.ts +9 -6
  3. package/lib/defaultFormat.js +9 -6
  4. package/lib/defaultFormat.js.map +1 -1
  5. package/lib/index.d.ts +46 -0
  6. package/lib/index.js +60 -37
  7. package/lib/index.js.map +1 -1
  8. package/lib/structures/ITtscLintConfig.d.ts +12 -6
  9. package/lib/structures/{ITtscLintFormatConfig.d.ts → ITtscLintFormat.d.ts} +2 -2
  10. package/lib/structures/{TtscLintRuleMap.js → ITtscLintFormat.js} +1 -1
  11. package/lib/structures/ITtscLintFormat.js.map +1 -0
  12. package/lib/structures/TtscLintRuleSetting.d.ts +49 -0
  13. package/lib/structures/{TtscLintRuleOptions.js → TtscLintRuleSetting.js} +1 -1
  14. package/lib/structures/TtscLintRuleSetting.js.map +1 -0
  15. package/lib/structures/index.d.ts +3 -4
  16. package/lib/structures/index.js +3 -4
  17. package/lib/structures/index.js.map +1 -1
  18. package/lib/structures/rules/ITtscLintBoundariesRuleOptions.d.ts +104 -0
  19. package/lib/structures/rules/ITtscLintBoundariesRuleOptions.js +14 -0
  20. package/lib/structures/rules/ITtscLintBoundariesRuleOptions.js.map +1 -0
  21. package/lib/structures/rules/ITtscLintBoundariesRules.d.ts +79 -0
  22. package/lib/structures/rules/ITtscLintBoundariesRules.js +3 -0
  23. package/lib/structures/rules/ITtscLintBoundariesRules.js.map +1 -0
  24. package/lib/structures/rules/ITtscLintContributorRules.d.ts +17 -0
  25. package/lib/structures/rules/ITtscLintContributorRules.js +3 -0
  26. package/lib/structures/rules/ITtscLintContributorRules.js.map +1 -0
  27. package/lib/structures/rules/ITtscLintCoreRules.d.ts +1257 -0
  28. package/lib/structures/{ITtscLintFormatConfig.js → rules/ITtscLintCoreRules.js} +1 -1
  29. package/lib/structures/rules/ITtscLintCoreRules.js.map +1 -0
  30. package/lib/structures/rules/ITtscLintCypressRuleOptions.d.ts +17 -0
  31. package/lib/structures/rules/ITtscLintCypressRuleOptions.js +10 -0
  32. package/lib/structures/rules/ITtscLintCypressRuleOptions.js.map +1 -0
  33. package/lib/structures/rules/ITtscLintCypressRules.d.ts +129 -0
  34. package/lib/structures/rules/ITtscLintCypressRules.js +3 -0
  35. package/lib/structures/rules/ITtscLintCypressRules.js.map +1 -0
  36. package/lib/structures/rules/ITtscLintFunctionalRuleOptions.d.ts +157 -0
  37. package/lib/structures/rules/ITtscLintFunctionalRuleOptions.js +13 -0
  38. package/lib/structures/rules/ITtscLintFunctionalRuleOptions.js.map +1 -0
  39. package/lib/structures/rules/ITtscLintFunctionalRules.d.ts +167 -0
  40. package/lib/structures/rules/ITtscLintFunctionalRules.js +3 -0
  41. package/lib/structures/rules/ITtscLintFunctionalRules.js.map +1 -0
  42. package/lib/structures/rules/ITtscLintJestRules.d.ts +201 -0
  43. package/lib/structures/rules/ITtscLintJestRules.js +3 -0
  44. package/lib/structures/rules/ITtscLintJestRules.js.map +1 -0
  45. package/lib/structures/rules/ITtscLintJsdocRules.d.ts +140 -0
  46. package/lib/structures/rules/ITtscLintJsdocRules.js +3 -0
  47. package/lib/structures/rules/ITtscLintJsdocRules.js.map +1 -0
  48. package/lib/structures/rules/ITtscLintJsxA11yRules.d.ts +302 -0
  49. package/lib/structures/rules/ITtscLintJsxA11yRules.js +3 -0
  50. package/lib/structures/rules/ITtscLintJsxA11yRules.js.map +1 -0
  51. package/lib/structures/rules/ITtscLintNextjsRules.d.ts +185 -0
  52. package/lib/structures/rules/ITtscLintNextjsRules.js +3 -0
  53. package/lib/structures/rules/ITtscLintNextjsRules.js.map +1 -0
  54. package/lib/structures/rules/ITtscLintPlaywrightRules.d.ts +330 -0
  55. package/lib/structures/rules/ITtscLintPlaywrightRules.js +3 -0
  56. package/lib/structures/rules/ITtscLintPlaywrightRules.js.map +1 -0
  57. package/lib/structures/rules/ITtscLintPromiseRules.d.ts +188 -0
  58. package/lib/structures/rules/ITtscLintPromiseRules.js +3 -0
  59. package/lib/structures/rules/ITtscLintPromiseRules.js.map +1 -0
  60. package/lib/structures/rules/ITtscLintReactPerfRuleOptions.d.ts +18 -0
  61. package/lib/structures/rules/ITtscLintReactPerfRuleOptions.js +8 -0
  62. package/lib/structures/rules/ITtscLintReactPerfRuleOptions.js.map +1 -0
  63. package/lib/structures/rules/ITtscLintReactPerfRules.d.ts +51 -0
  64. package/lib/structures/rules/ITtscLintReactPerfRules.js +3 -0
  65. package/lib/structures/rules/ITtscLintReactPerfRules.js.map +1 -0
  66. package/lib/structures/rules/ITtscLintReactRuleOptions.d.ts +39 -0
  67. package/lib/structures/rules/ITtscLintReactRuleOptions.js +12 -0
  68. package/lib/structures/rules/ITtscLintReactRuleOptions.js.map +1 -0
  69. package/lib/structures/rules/ITtscLintReactRules.d.ts +289 -0
  70. package/lib/structures/rules/ITtscLintReactRules.js +3 -0
  71. package/lib/structures/rules/ITtscLintReactRules.js.map +1 -0
  72. package/lib/structures/rules/ITtscLintRegexpRules.d.ts +190 -0
  73. package/lib/structures/rules/ITtscLintRegexpRules.js +3 -0
  74. package/lib/structures/rules/ITtscLintRegexpRules.js.map +1 -0
  75. package/lib/structures/rules/ITtscLintRuleOptionsMap.d.ts +66 -0
  76. package/lib/structures/rules/ITtscLintRuleOptionsMap.js +3 -0
  77. package/lib/structures/rules/ITtscLintRuleOptionsMap.js.map +1 -0
  78. package/lib/structures/rules/ITtscLintRules.d.ts +55 -0
  79. package/lib/structures/{TtscLintRule.js → rules/ITtscLintRules.js} +1 -1
  80. package/lib/structures/rules/ITtscLintRules.js.map +1 -0
  81. package/lib/structures/rules/ITtscLintSecurityRules.d.ts +148 -0
  82. package/lib/structures/rules/ITtscLintSecurityRules.js +3 -0
  83. package/lib/structures/rules/ITtscLintSecurityRules.js.map +1 -0
  84. package/lib/structures/rules/ITtscLintSolidRules.d.ts +181 -0
  85. package/lib/structures/rules/ITtscLintSolidRules.js +3 -0
  86. package/lib/structures/rules/ITtscLintSolidRules.js.map +1 -0
  87. package/lib/structures/rules/ITtscLintStorybookRuleOptions.d.ts +21 -0
  88. package/lib/structures/rules/ITtscLintStorybookRuleOptions.js +9 -0
  89. package/lib/structures/rules/ITtscLintStorybookRuleOptions.js.map +1 -0
  90. package/lib/structures/rules/ITtscLintStorybookRules.d.ts +174 -0
  91. package/lib/structures/rules/ITtscLintStorybookRules.js +3 -0
  92. package/lib/structures/rules/ITtscLintStorybookRules.js.map +1 -0
  93. package/lib/structures/rules/ITtscLintTanstackQueryRules.d.ts +94 -0
  94. package/lib/structures/rules/ITtscLintTanstackQueryRules.js +3 -0
  95. package/lib/structures/rules/ITtscLintTanstackQueryRules.js.map +1 -0
  96. package/lib/structures/rules/ITtscLintTestingLibraryRuleOptions.d.ts +22 -0
  97. package/lib/structures/rules/ITtscLintTestingLibraryRuleOptions.js +10 -0
  98. package/lib/structures/rules/ITtscLintTestingLibraryRuleOptions.js.map +1 -0
  99. package/lib/structures/rules/ITtscLintTestingLibraryRules.d.ts +310 -0
  100. package/lib/structures/rules/ITtscLintTestingLibraryRules.js +3 -0
  101. package/lib/structures/rules/ITtscLintTestingLibraryRules.js.map +1 -0
  102. package/lib/structures/rules/ITtscLintTypeScriptRules.d.ts +1132 -0
  103. package/lib/structures/rules/ITtscLintTypeScriptRules.js +3 -0
  104. package/lib/structures/rules/ITtscLintTypeScriptRules.js.map +1 -0
  105. package/lib/structures/rules/ITtscLintUnicornRules.d.ts +997 -0
  106. package/lib/structures/rules/ITtscLintUnicornRules.js +3 -0
  107. package/lib/structures/rules/ITtscLintUnicornRules.js.map +1 -0
  108. package/lib/structures/rules/ITtscLintVitestRules.d.ts +141 -0
  109. package/lib/structures/rules/ITtscLintVitestRules.js +3 -0
  110. package/lib/structures/rules/ITtscLintVitestRules.js.map +1 -0
  111. package/lib/structures/rules/index.d.ts +31 -0
  112. package/lib/structures/rules/index.js +48 -0
  113. package/lib/structures/rules/index.js.map +1 -0
  114. package/linthost/ast_helpers.go +30 -5
  115. package/linthost/compile.go +33 -2
  116. package/linthost/config.go +48 -17
  117. package/linthost/config_format.go +9 -9
  118. package/linthost/directives.go +67 -25
  119. package/linthost/dispatch.go +14 -3
  120. package/linthost/engine.go +160 -40
  121. package/linthost/fix.go +2 -2
  122. package/linthost/flags_gen.go +17 -15
  123. package/linthost/host.go +40 -3
  124. package/linthost/lsp.go +747 -0
  125. package/linthost/print_dispatch.go +2 -2
  126. package/linthost/print_nodes_function.go +2 -2
  127. package/linthost/print_nodes_object.go +1 -1
  128. package/linthost/rule_names.go +14 -0
  129. package/linthost/rules_arrays.go +2 -2
  130. package/linthost/rules_boundaries.go +532 -0
  131. package/linthost/rules_camelcase.go +133 -0
  132. package/linthost/rules_complexity.go +94 -0
  133. package/linthost/rules_consistent_return.go +130 -0
  134. package/linthost/rules_console.go +1 -1
  135. package/linthost/rules_core_extra.go +739 -0
  136. package/linthost/rules_curly.go +70 -0
  137. package/linthost/rules_cypress.go +608 -0
  138. package/linthost/rules_debugger.go +2 -2
  139. package/linthost/rules_default_case.go +39 -0
  140. package/linthost/rules_default_case_last.go +46 -0
  141. package/linthost/rules_dupes.go +3 -3
  142. package/linthost/rules_empty.go +3 -3
  143. package/linthost/rules_escape.go +44 -24
  144. package/linthost/rules_eval.go +2 -2
  145. package/linthost/rules_finally.go +2 -2
  146. package/linthost/rules_format_jsdoc.go +1 -1
  147. package/linthost/rules_format_print_width.go +9 -9
  148. package/linthost/rules_format_quotes.go +1 -1
  149. package/linthost/rules_format_semi.go +1 -1
  150. package/linthost/rules_format_sort_imports.go +1 -1
  151. package/linthost/rules_format_trailing_comma.go +1 -1
  152. package/linthost/rules_functional.go +967 -0
  153. package/linthost/rules_gap.go +24 -45
  154. package/linthost/rules_grouped_accessor_pairs.go +87 -0
  155. package/linthost/rules_guard_for_in.go +198 -0
  156. package/linthost/rules_id_length.go +77 -0
  157. package/linthost/rules_imports.go +70 -2
  158. package/linthost/rules_init_declarations.go +53 -0
  159. package/linthost/rules_jest.go +618 -0
  160. package/linthost/rules_jsdoc.go +502 -0
  161. package/linthost/rules_jsx_a11y.go +1264 -0
  162. package/linthost/rules_logic.go +12 -12
  163. package/linthost/rules_loops.go +1 -1
  164. package/linthost/rules_max_classes_per_file.go +58 -0
  165. package/linthost/rules_max_depth.go +83 -0
  166. package/linthost/rules_max_lines.go +101 -0
  167. package/linthost/rules_max_lines_per_function.go +57 -0
  168. package/linthost/rules_max_nested_callbacks.go +61 -0
  169. package/linthost/rules_max_params.go +49 -0
  170. package/linthost/rules_max_statements.go +59 -0
  171. package/linthost/rules_misc.go +1 -1
  172. package/linthost/rules_nextjs.go +697 -0
  173. package/linthost/rules_no_else_return.go +75 -0
  174. package/linthost/rules_no_empty_named_blocks.go +91 -0
  175. package/linthost/rules_no_extend_native.go +51 -0
  176. package/linthost/rules_no_import_assign.go +140 -0
  177. package/linthost/rules_no_invalid_this.go +52 -0
  178. package/linthost/rules_no_loop_func.go +85 -0
  179. package/linthost/rules_no_magic_numbers.go +123 -0
  180. package/linthost/rules_no_mixed_operators.go +80 -0
  181. package/linthost/rules_no_param_reassign.go +98 -0
  182. package/linthost/rules_no_redeclare.go +270 -0
  183. package/linthost/rules_no_restricted_imports.go +105 -0
  184. package/linthost/rules_no_restricted_syntax.go +49 -0
  185. package/linthost/rules_no_shadow.go +147 -0
  186. package/linthost/rules_no_unreachable.go +77 -0
  187. package/linthost/rules_no_useless_assignment.go +120 -0
  188. package/linthost/rules_no_useless_constructor.go +245 -0
  189. package/linthost/rules_no_useless_return.go +51 -0
  190. package/linthost/rules_params.go +1 -1
  191. package/linthost/rules_playwright.go +788 -0
  192. package/linthost/rules_prefer_arrow_callback.go +124 -0
  193. package/linthost/rules_prefer_destructuring.go +98 -0
  194. package/linthost/rules_prefer_named_capture_group.go +129 -0
  195. package/linthost/rules_prefer_rest_params.go +94 -0
  196. package/linthost/rules_problems.go +41 -30
  197. package/linthost/rules_promise.go +1128 -73
  198. package/linthost/rules_protos.go +2 -2
  199. package/linthost/rules_react.go +773 -0
  200. package/linthost/rules_react_extras.go +227 -0
  201. package/linthost/rules_react_hooks.go +848 -0
  202. package/linthost/rules_react_perf.go +293 -0
  203. package/linthost/rules_react_refresh.go +583 -0
  204. package/linthost/rules_regexp.go +410 -0
  205. package/linthost/rules_security.go +830 -0
  206. package/linthost/rules_self.go +2 -2
  207. package/linthost/rules_solid.go +1073 -0
  208. package/linthost/rules_sort_imports.go +69 -0
  209. package/linthost/rules_sort_keys.go +134 -0
  210. package/linthost/rules_storybook.go +1176 -0
  211. package/linthost/rules_strings.go +4 -4
  212. package/linthost/rules_suggestions.go +38 -38
  213. package/linthost/rules_tanstack_query.go +844 -0
  214. package/linthost/rules_testing_library.go +1204 -0
  215. package/linthost/rules_throw.go +1 -1
  216. package/linthost/rules_ts.go +19 -19
  217. package/linthost/rules_ts_async.go +399 -0
  218. package/linthost/rules_ts_class_literal_property_style.go +115 -0
  219. package/linthost/rules_ts_consistent_type_exports.go +256 -0
  220. package/linthost/rules_ts_explicit_function_return_type.go +67 -0
  221. package/linthost/rules_ts_extra.go +155 -36
  222. package/linthost/rules_ts_no_base_to_string.go +218 -0
  223. package/linthost/rules_ts_no_confusing_void.go +72 -0
  224. package/linthost/rules_ts_no_deprecated.go +195 -0
  225. package/linthost/rules_ts_no_for_in_array.go +84 -0
  226. package/linthost/rules_ts_no_magic_numbers.go +124 -0
  227. package/linthost/rules_ts_no_meaningless_void_operator.go +84 -0
  228. package/linthost/rules_ts_no_misused_spread.go +104 -0
  229. package/linthost/rules_ts_no_redundant_type_constituents.go +113 -0
  230. package/linthost/rules_ts_no_restricted_types.go +62 -0
  231. package/linthost/rules_ts_no_unnecessary_boolean_literal_compare.go +129 -0
  232. package/linthost/rules_ts_no_unnecessary_condition.go +250 -0
  233. package/linthost/rules_ts_no_unnecessary_qualifier.go +118 -0
  234. package/linthost/rules_ts_no_unnecessary_template_expression.go +178 -0
  235. package/linthost/rules_ts_no_unnecessary_type_arguments.go +234 -0
  236. package/linthost/rules_ts_no_unnecessary_type_assertion.go +157 -0
  237. package/linthost/rules_ts_no_unsafe_argument.go +82 -0
  238. package/linthost/rules_ts_no_unsafe_assignment.go +102 -0
  239. package/linthost/rules_ts_no_unsafe_call.go +82 -0
  240. package/linthost/rules_ts_no_unsafe_enum_comparison.go +235 -0
  241. package/linthost/rules_ts_no_unsafe_member_access.go +58 -0
  242. package/linthost/rules_ts_no_unsafe_return.go +126 -0
  243. package/linthost/rules_ts_no_unsafe_unary_minus.go +81 -0
  244. package/linthost/rules_ts_no_useless_constructor.go +52 -0
  245. package/linthost/rules_ts_non_nullable_type_assertion_style.go +108 -0
  246. package/linthost/rules_ts_parameter_properties.go +38 -0
  247. package/linthost/rules_ts_prefer_find.go +178 -0
  248. package/linthost/rules_ts_prefer_includes.go +255 -0
  249. package/linthost/rules_ts_prefer_nullish_coalescing.go +104 -0
  250. package/linthost/rules_ts_prefer_optional_chain.go +228 -0
  251. package/linthost/rules_ts_prefer_promise_reject_errors.go +176 -0
  252. package/linthost/rules_ts_prefer_readonly.go +73 -0
  253. package/linthost/rules_ts_prefer_reduce_type_parameter.go +116 -0
  254. package/linthost/rules_ts_prefer_regexp_exec.go +122 -0
  255. package/linthost/rules_ts_prefer_return_this_type.go +135 -0
  256. package/linthost/rules_ts_prefer_string_starts_ends_with.go +360 -0
  257. package/linthost/rules_ts_promise_function_async.go +77 -0
  258. package/linthost/rules_ts_related_getter_setter_pairs.go +113 -0
  259. package/linthost/rules_ts_require_array_sort_compare.go +96 -0
  260. package/linthost/rules_ts_restrict_plus_operands.go +127 -0
  261. package/linthost/rules_ts_restrict_template_expressions.go +95 -0
  262. package/linthost/rules_ts_simple.go +387 -0
  263. package/linthost/rules_ts_sort_type_constituents.go +144 -0
  264. package/linthost/rules_ts_strict_boolean_expressions.go +157 -0
  265. package/linthost/rules_ts_switch_exhaustiveness_check.go +147 -0
  266. package/linthost/rules_ts_unbound_method.go +126 -0
  267. package/linthost/rules_tsdoc.go +136 -0
  268. package/linthost/rules_unicorn_better_regex.go +27 -0
  269. package/linthost/rules_unicorn_catch_error_name.go +46 -0
  270. package/linthost/rules_unicorn_consistent_assert.go +47 -0
  271. package/linthost/rules_unicorn_consistent_date_clone.go +54 -0
  272. package/linthost/rules_unicorn_consistent_destructuring.go +25 -0
  273. package/linthost/rules_unicorn_consistent_empty_array_spread.go +62 -0
  274. package/linthost/rules_unicorn_consistent_existence_index_check.go +80 -0
  275. package/linthost/rules_unicorn_consistent_function_scoping.go +25 -0
  276. package/linthost/rules_unicorn_consistent_template_literal_escape.go +25 -0
  277. package/linthost/rules_unicorn_custom_error_definition.go +138 -0
  278. package/linthost/rules_unicorn_empty_brace_spaces.go +73 -0
  279. package/linthost/rules_unicorn_error_message.go +64 -0
  280. package/linthost/rules_unicorn_escape_case.go +51 -0
  281. package/linthost/rules_unicorn_expiring_todo_comments.go +78 -0
  282. package/linthost/rules_unicorn_explicit_length_check.go +88 -0
  283. package/linthost/rules_unicorn_filename_case.go +29 -0
  284. package/linthost/rules_unicorn_import_style.go +28 -0
  285. package/linthost/rules_unicorn_isolated_functions.go +29 -0
  286. package/linthost/rules_unicorn_new_for_builtins.go +87 -0
  287. package/linthost/rules_unicorn_no_abusive_eslint_disable.go +63 -0
  288. package/linthost/rules_unicorn_no_accessor_recursion.go +115 -0
  289. package/linthost/rules_unicorn_no_anonymous_default_export.go +74 -0
  290. package/linthost/rules_unicorn_no_array_callback_reference.go +65 -0
  291. package/linthost/rules_unicorn_no_array_for_each.go +40 -0
  292. package/linthost/rules_unicorn_no_array_method_this_argument.go +61 -0
  293. package/linthost/rules_unicorn_no_array_reduce.go +41 -0
  294. package/linthost/rules_unicorn_no_array_reverse.go +44 -0
  295. package/linthost/rules_unicorn_no_array_sort.go +43 -0
  296. package/linthost/rules_unicorn_no_await_expression_member.go +40 -0
  297. package/linthost/rules_unicorn_no_await_in_promise_methods.go +69 -0
  298. package/linthost/rules_unicorn_no_console_spaces.go +61 -0
  299. package/linthost/rules_unicorn_no_document_cookie.go +41 -0
  300. package/linthost/rules_unicorn_no_empty_file.go +44 -0
  301. package/linthost/rules_unicorn_no_for_loop.go +102 -0
  302. package/linthost/rules_unicorn_no_hex_escape.go +42 -0
  303. package/linthost/rules_unicorn_no_immediate_mutation.go +90 -0
  304. package/linthost/rules_unicorn_no_instanceof_builtins.go +66 -0
  305. package/linthost/rules_unicorn_no_invalid_fetch_options.go +79 -0
  306. package/linthost/rules_unicorn_no_invalid_remove_event_listener.go +51 -0
  307. package/linthost/rules_unicorn_no_keyword_prefix.go +101 -0
  308. package/linthost/rules_unicorn_no_lonely_if.go +44 -0
  309. package/linthost/rules_unicorn_no_magic_array_flat_depth.go +51 -0
  310. package/linthost/rules_unicorn_no_named_default.go +54 -0
  311. package/linthost/rules_unicorn_no_negated_condition.go +85 -0
  312. package/linthost/rules_unicorn_no_negation_in_equality_check.go +50 -0
  313. package/linthost/rules_unicorn_no_nested_ternary.go +43 -0
  314. package/linthost/rules_unicorn_no_new_array.go +30 -0
  315. package/linthost/rules_unicorn_no_new_buffer.go +31 -0
  316. package/linthost/rules_unicorn_no_null.go +24 -0
  317. package/linthost/rules_unicorn_no_object_as_default_parameter.go +48 -0
  318. package/linthost/rules_unicorn_no_process_exit.go +43 -0
  319. package/linthost/rules_unicorn_no_single_promise_in_promise_methods.go +59 -0
  320. package/linthost/rules_unicorn_no_static_only_class.go +56 -0
  321. package/linthost/rules_unicorn_no_thenable.go +74 -0
  322. package/linthost/rules_unicorn_no_this_assignment.go +35 -0
  323. package/linthost/rules_unicorn_no_typeof_undefined.go +58 -0
  324. package/linthost/rules_unicorn_no_unnecessary_array_flat_depth.go +49 -0
  325. package/linthost/rules_unicorn_no_unnecessary_array_splice_count.go +70 -0
  326. package/linthost/rules_unicorn_no_unnecessary_await.go +51 -0
  327. package/linthost/rules_unicorn_no_unnecessary_polyfills.go +32 -0
  328. package/linthost/rules_unicorn_no_unnecessary_slice_end.go +48 -0
  329. package/linthost/rules_unicorn_no_unreadable_array_destructuring.go +115 -0
  330. package/linthost/rules_unicorn_no_unreadable_iife.go +50 -0
  331. package/linthost/rules_unicorn_no_unused_properties.go +30 -0
  332. package/linthost/rules_unicorn_no_useless_collection_argument.go +63 -0
  333. package/linthost/rules_unicorn_no_useless_error_capture_stack_trace.go +46 -0
  334. package/linthost/rules_unicorn_no_useless_fallback_in_spread.go +81 -0
  335. package/linthost/rules_unicorn_no_useless_iterator_to_array.go +72 -0
  336. package/linthost/rules_unicorn_no_useless_length_check.go +144 -0
  337. package/linthost/rules_unicorn_no_useless_promise_resolve_reject.go +81 -0
  338. package/linthost/rules_unicorn_no_useless_spread.go +67 -0
  339. package/linthost/rules_unicorn_no_useless_switch_case.go +55 -0
  340. package/linthost/rules_unicorn_no_useless_undefined.go +55 -0
  341. package/linthost/rules_unicorn_no_zero_fractions.go +52 -0
  342. package/linthost/rules_unicorn_number_literal_case.go +69 -0
  343. package/linthost/rules_unicorn_numeric_separators_style.go +75 -0
  344. package/linthost/rules_unicorn_prefer_add_event_listener.go +66 -0
  345. package/linthost/rules_unicorn_prefer_array_find.go +51 -0
  346. package/linthost/rules_unicorn_prefer_array_flat.go +52 -0
  347. package/linthost/rules_unicorn_prefer_array_flat_map.go +63 -0
  348. package/linthost/rules_unicorn_prefer_array_index_of.go +147 -0
  349. package/linthost/rules_unicorn_prefer_array_some.go +67 -0
  350. package/linthost/rules_unicorn_prefer_at.go +77 -0
  351. package/linthost/rules_unicorn_prefer_bigint_literals.go +77 -0
  352. package/linthost/rules_unicorn_prefer_blob_reading_methods.go +44 -0
  353. package/linthost/rules_unicorn_prefer_class_fields.go +93 -0
  354. package/linthost/rules_unicorn_prefer_classlist_toggle.go +120 -0
  355. package/linthost/rules_unicorn_prefer_code_point.go +49 -0
  356. package/linthost/rules_unicorn_prefer_date_now.go +78 -0
  357. package/linthost/rules_unicorn_prefer_default_parameters.go +144 -0
  358. package/linthost/rules_unicorn_prefer_dom_node_append.go +40 -0
  359. package/linthost/rules_unicorn_prefer_dom_node_dataset.go +55 -0
  360. package/linthost/rules_unicorn_prefer_dom_node_remove.go +41 -0
  361. package/linthost/rules_unicorn_prefer_dom_node_text_content.go +37 -0
  362. package/linthost/rules_unicorn_prefer_event_target.go +36 -0
  363. package/linthost/rules_unicorn_prefer_export_from.go +129 -0
  364. package/linthost/rules_unicorn_prefer_global_this.go +127 -0
  365. package/linthost/rules_unicorn_prefer_import_meta_properties.go +66 -0
  366. package/linthost/rules_unicorn_prefer_includes.go +149 -0
  367. package/linthost/rules_unicorn_prefer_json_parse_buffer.go +65 -0
  368. package/linthost/rules_unicorn_prefer_keyboard_event_key.go +38 -0
  369. package/linthost/rules_unicorn_prefer_logical_operator_over_ternary.go +48 -0
  370. package/linthost/rules_unicorn_prefer_math_min_max.go +60 -0
  371. package/linthost/rules_unicorn_prefer_math_trunc.go +62 -0
  372. package/linthost/rules_unicorn_prefer_modern_dom_apis.go +47 -0
  373. package/linthost/rules_unicorn_prefer_modern_math_apis.go +70 -0
  374. package/linthost/rules_unicorn_prefer_module.go +50 -0
  375. package/linthost/rules_unicorn_prefer_native_coercion_functions.go +114 -0
  376. package/linthost/rules_unicorn_prefer_negative_index.go +74 -0
  377. package/linthost/rules_unicorn_prefer_node_protocol.go +122 -0
  378. package/linthost/rules_unicorn_prefer_number_properties.go +88 -0
  379. package/linthost/rules_unicorn_prefer_object_from_entries.go +55 -0
  380. package/linthost/rules_unicorn_prefer_optional_catch_binding.go +62 -0
  381. package/linthost/rules_unicorn_prefer_prototype_methods.go +54 -0
  382. package/linthost/rules_unicorn_prefer_query_selector.go +56 -0
  383. package/linthost/rules_unicorn_prefer_reflect_apply.go +36 -0
  384. package/linthost/rules_unicorn_prefer_regexp_test_rule.go +80 -0
  385. package/linthost/rules_unicorn_prefer_response_static_json.go +53 -0
  386. package/linthost/rules_unicorn_prefer_set_has.go +42 -0
  387. package/linthost/rules_unicorn_prefer_set_size.go +48 -0
  388. package/linthost/rules_unicorn_prefer_simple_condition_first.go +34 -0
  389. package/linthost/rules_unicorn_prefer_single_call.go +96 -0
  390. package/linthost/rules_unicorn_prefer_spread.go +51 -0
  391. package/linthost/rules_unicorn_prefer_string_raw.go +43 -0
  392. package/linthost/rules_unicorn_prefer_string_replace_all.go +95 -0
  393. package/linthost/rules_unicorn_prefer_string_slice.go +43 -0
  394. package/linthost/rules_unicorn_prefer_string_starts_ends_with.go +148 -0
  395. package/linthost/rules_unicorn_prefer_string_trim_start_end.go +48 -0
  396. package/linthost/rules_unicorn_prefer_structured_clone.go +71 -0
  397. package/linthost/rules_unicorn_prefer_switch.go +103 -0
  398. package/linthost/rules_unicorn_prefer_ternary.go +71 -0
  399. package/linthost/rules_unicorn_prefer_top_level_await.go +72 -0
  400. package/linthost/rules_unicorn_prefer_type_error.go +127 -0
  401. package/linthost/rules_unicorn_prevent_abbreviations.go +127 -0
  402. package/linthost/rules_unicorn_relative_url_style.go +49 -0
  403. package/linthost/rules_unicorn_require_array_join_separator.go +45 -0
  404. package/linthost/rules_unicorn_require_module_attributes.go +54 -0
  405. package/linthost/rules_unicorn_require_module_specifiers.go +55 -0
  406. package/linthost/rules_unicorn_require_number_to_fixed_digits_argument.go +43 -0
  407. package/linthost/rules_unicorn_require_post_message_target_origin.go +44 -0
  408. package/linthost/rules_unicorn_string_content.go +27 -0
  409. package/linthost/rules_unicorn_switch_case_braces.go +42 -0
  410. package/linthost/rules_unicorn_switch_case_break_position.go +31 -0
  411. package/linthost/rules_unicorn_template_indent.go +28 -0
  412. package/linthost/rules_unicorn_text_encoding_identifier_case.go +72 -0
  413. package/linthost/rules_unicorn_throw_new_error.go +61 -0
  414. package/linthost/rules_var.go +10 -4
  415. package/linthost/rules_vitest.go +568 -0
  416. package/package.json +3 -3
  417. package/plugin/main.go +49 -3
  418. package/rule/astutil/astutil.go +10 -3
  419. package/rule/rule.go +12 -10
  420. package/src/defaultFormat.ts +11 -8
  421. package/src/index.ts +65 -43
  422. package/src/structures/ITtscLintConfig.ts +12 -6
  423. package/src/structures/{ITtscLintFormatConfig.ts → ITtscLintFormat.ts} +2 -2
  424. package/src/structures/TtscLintRuleSetting.ts +55 -0
  425. package/src/structures/index.ts +3 -4
  426. package/src/structures/rules/ITtscLintBoundariesRuleOptions.ts +128 -0
  427. package/src/structures/rules/ITtscLintBoundariesRules.ts +95 -0
  428. package/src/structures/rules/ITtscLintContributorRules.ts +21 -0
  429. package/src/structures/rules/ITtscLintCoreRules.ts +1406 -0
  430. package/src/structures/rules/ITtscLintCypressRuleOptions.ts +18 -0
  431. package/src/structures/rules/ITtscLintCypressRules.ts +145 -0
  432. package/src/structures/rules/ITtscLintFunctionalRuleOptions.ts +213 -0
  433. package/src/structures/rules/ITtscLintFunctionalRules.ts +202 -0
  434. package/src/structures/rules/ITtscLintJestRules.ts +220 -0
  435. package/src/structures/rules/ITtscLintJsdocRules.ts +153 -0
  436. package/src/structures/rules/ITtscLintJsxA11yRules.ts +339 -0
  437. package/src/structures/rules/ITtscLintNextjsRules.ts +206 -0
  438. package/src/structures/rules/ITtscLintPlaywrightRules.ts +361 -0
  439. package/src/structures/rules/ITtscLintPromiseRules.ts +205 -0
  440. package/src/structures/rules/ITtscLintReactPerfRuleOptions.ts +19 -0
  441. package/src/structures/rules/ITtscLintReactPerfRules.ts +55 -0
  442. package/src/structures/rules/ITtscLintReactRuleOptions.ts +43 -0
  443. package/src/structures/rules/ITtscLintReactRules.ts +321 -0
  444. package/src/structures/rules/ITtscLintRegexpRules.ts +212 -0
  445. package/src/structures/rules/ITtscLintRuleOptionsMap.ts +89 -0
  446. package/src/structures/rules/ITtscLintRules.ts +77 -0
  447. package/src/structures/rules/ITtscLintSecurityRules.ts +162 -0
  448. package/src/structures/rules/ITtscLintSolidRules.ts +202 -0
  449. package/src/structures/rules/ITtscLintStorybookRuleOptions.ts +23 -0
  450. package/src/structures/rules/ITtscLintStorybookRules.ts +193 -0
  451. package/src/structures/rules/ITtscLintTanstackQueryRules.ts +102 -0
  452. package/src/structures/rules/ITtscLintTestingLibraryRuleOptions.ts +24 -0
  453. package/src/structures/rules/ITtscLintTestingLibraryRules.ts +342 -0
  454. package/src/structures/rules/ITtscLintTypeScriptRules.ts +1230 -0
  455. package/src/structures/rules/ITtscLintUnicornRules.ts +1143 -0
  456. package/src/structures/rules/ITtscLintVitestRules.ts +154 -0
  457. package/src/structures/rules/index.ts +31 -0
  458. package/lib/structures/ITtscLintFormatConfig.js.map +0 -1
  459. package/lib/structures/TtscLintRule.d.ts +0 -17
  460. package/lib/structures/TtscLintRule.js.map +0 -1
  461. package/lib/structures/TtscLintRuleMap.d.ts +0 -46
  462. package/lib/structures/TtscLintRuleMap.js.map +0 -1
  463. package/lib/structures/TtscLintRuleOptions.d.ts +0 -137
  464. package/lib/structures/TtscLintRuleOptions.js.map +0 -1
  465. package/src/structures/TtscLintRule.ts +0 -160
  466. package/src/structures/TtscLintRuleMap.ts +0 -55
  467. package/src/structures/TtscLintRuleOptions.ts +0 -151
@@ -0,0 +1,147 @@
1
+ // unicorn/prefer-array-index-of: `arr.findIndex(x => x === literal)` is
2
+ // the long-hand spelling of `arr.indexOf(literal)`. Both return the
3
+ // index of the first matching element; `indexOf` is a direct comparison
4
+ // against a value and is faster, shorter, and clearer about intent.
5
+ //
6
+ // AST-only: visit each `CallExpression` whose callee is
7
+ // `PropertyAccess(_, findIndex)`. The single argument must be a
8
+ // function (`ArrowFunction` or `FunctionExpression`) with exactly one
9
+ // parameter. The function body — concise body, or a block body whose
10
+ // single statement is a `return` — must be a strict-equality comparison
11
+ // between the parameter identifier and a literal (string, number,
12
+ // boolean, null, bigint). Reports on the call.
13
+ // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-array-index-of.md
14
+ package linthost
15
+
16
+ import shimast "github.com/microsoft/typescript-go/shim/ast"
17
+
18
+ type unicornPreferArrayIndexOf struct{}
19
+
20
+ func (unicornPreferArrayIndexOf) Name() string { return "unicorn/prefer-array-index-of" }
21
+ func (unicornPreferArrayIndexOf) Visits() []shimast.Kind {
22
+ return []shimast.Kind{shimast.KindCallExpression}
23
+ }
24
+ func (unicornPreferArrayIndexOf) Check(ctx *Context, node *shimast.Node) {
25
+ call := node.AsCallExpression()
26
+ if call == nil || call.Expression == nil ||
27
+ call.Expression.Kind != shimast.KindPropertyAccessExpression {
28
+ return
29
+ }
30
+ access := call.Expression.AsPropertyAccessExpression()
31
+ if access == nil || identifierText(access.Name()) != "findIndex" {
32
+ return
33
+ }
34
+ if call.Arguments == nil || len(call.Arguments.Nodes) != 1 {
35
+ return
36
+ }
37
+ fn := stripParens(call.Arguments.Nodes[0])
38
+ if fn == nil {
39
+ return
40
+ }
41
+ var body *shimast.Node
42
+ switch fn.Kind {
43
+ case shimast.KindArrowFunction:
44
+ arrow := fn.AsArrowFunction()
45
+ if arrow == nil {
46
+ return
47
+ }
48
+ body = arrow.Body
49
+ case shimast.KindFunctionExpression:
50
+ expr := fn.AsFunctionExpression()
51
+ if expr == nil {
52
+ return
53
+ }
54
+ body = expr.Body
55
+ default:
56
+ return
57
+ }
58
+ params := fn.Parameters()
59
+ if len(params) != 1 {
60
+ return
61
+ }
62
+ paramName := parameterIdentifierName(params[0])
63
+ if paramName == "" {
64
+ return
65
+ }
66
+ expr := unicornPreferArrayIndexOfBodyExpression(body)
67
+ if expr == nil {
68
+ return
69
+ }
70
+ bin := expr.AsBinaryExpression()
71
+ if bin == nil || bin.OperatorToken == nil ||
72
+ bin.OperatorToken.Kind != shimast.KindEqualsEqualsEqualsToken {
73
+ return
74
+ }
75
+ left := stripParens(bin.Left)
76
+ right := stripParens(bin.Right)
77
+ if left == nil || right == nil {
78
+ return
79
+ }
80
+ if unicornPreferArrayIndexOfMatchesParam(left, paramName) &&
81
+ unicornPreferArrayIndexOfIsLiteral(right) {
82
+ ctx.Report(node, "Prefer `Array#indexOf()` over `Array#findIndex(x => x === literal)`.")
83
+ return
84
+ }
85
+ if unicornPreferArrayIndexOfMatchesParam(right, paramName) &&
86
+ unicornPreferArrayIndexOfIsLiteral(left) {
87
+ ctx.Report(node, "Prefer `Array#indexOf()` over `Array#findIndex(x => x === literal)`.")
88
+ }
89
+ }
90
+
91
+ // unicornPreferArrayIndexOfBodyExpression normalizes the function body to
92
+ // the comparison expression: a concise arrow body returns its expression,
93
+ // a block body with a single `return expr;` returns the expression.
94
+ func unicornPreferArrayIndexOfBodyExpression(body *shimast.Node) *shimast.Node {
95
+ if body == nil {
96
+ return nil
97
+ }
98
+ if body.Kind != shimast.KindBlock {
99
+ expr := stripParens(body)
100
+ if expr == nil || expr.Kind != shimast.KindBinaryExpression {
101
+ return nil
102
+ }
103
+ return expr
104
+ }
105
+ block := body.AsBlock()
106
+ if block == nil || block.Statements == nil || len(block.Statements.Nodes) != 1 {
107
+ return nil
108
+ }
109
+ stmt := block.Statements.Nodes[0]
110
+ if stmt == nil || stmt.Kind != shimast.KindReturnStatement {
111
+ return nil
112
+ }
113
+ ret := stmt.AsReturnStatement()
114
+ if ret == nil || ret.Expression == nil {
115
+ return nil
116
+ }
117
+ expr := stripParens(ret.Expression)
118
+ if expr == nil || expr.Kind != shimast.KindBinaryExpression {
119
+ return nil
120
+ }
121
+ return expr
122
+ }
123
+
124
+ func unicornPreferArrayIndexOfMatchesParam(node *shimast.Node, name string) bool {
125
+ return identifierText(node) == name
126
+ }
127
+
128
+ func unicornPreferArrayIndexOfIsLiteral(node *shimast.Node) bool {
129
+ if node == nil {
130
+ return false
131
+ }
132
+ switch node.Kind {
133
+ case shimast.KindStringLiteral,
134
+ shimast.KindNumericLiteral,
135
+ shimast.KindBigIntLiteral,
136
+ shimast.KindNoSubstitutionTemplateLiteral,
137
+ shimast.KindNullKeyword,
138
+ shimast.KindTrueKeyword,
139
+ shimast.KindFalseKeyword:
140
+ return true
141
+ }
142
+ return false
143
+ }
144
+
145
+ func init() {
146
+ Register(unicornPreferArrayIndexOf{})
147
+ }
@@ -0,0 +1,67 @@
1
+ // unicorn/prefer-array-some: `arr.filter(predicate).length > 0` walks the
2
+ // whole array and allocates an intermediate filtered array just to ask
3
+ // the boolean question "does any element match?". `arr.some(predicate)`
4
+ // short-circuits at the first hit and reads as the intent.
5
+ //
6
+ // AST-only: visit each `BinaryExpression`. The operator must be one of
7
+ // `>`, `>=`, `!==`, `!=`. The left operand must be
8
+ // `PropertyAccess(CallExpression(_, filter), length)`. The right operand
9
+ // must be the numeric literal `0`. Reports on the binary expression.
10
+ // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-array-some.md
11
+ package linthost
12
+
13
+ import shimast "github.com/microsoft/typescript-go/shim/ast"
14
+
15
+ type unicornPreferArraySome struct{}
16
+
17
+ func (unicornPreferArraySome) Name() string { return "unicorn/prefer-array-some" }
18
+ func (unicornPreferArraySome) Visits() []shimast.Kind {
19
+ return []shimast.Kind{shimast.KindBinaryExpression}
20
+ }
21
+ func (unicornPreferArraySome) Check(ctx *Context, node *shimast.Node) {
22
+ bin := node.AsBinaryExpression()
23
+ if bin == nil || bin.OperatorToken == nil || bin.Left == nil || bin.Right == nil {
24
+ return
25
+ }
26
+ switch bin.OperatorToken.Kind {
27
+ case shimast.KindGreaterThanToken,
28
+ shimast.KindGreaterThanEqualsToken,
29
+ shimast.KindExclamationEqualsEqualsToken,
30
+ shimast.KindExclamationEqualsToken:
31
+ default:
32
+ return
33
+ }
34
+ right := stripParens(bin.Right)
35
+ if right == nil || right.Kind != shimast.KindNumericLiteral {
36
+ return
37
+ }
38
+ if numericLiteralText(right) != "0" {
39
+ return
40
+ }
41
+ left := stripParens(bin.Left)
42
+ if left == nil || left.Kind != shimast.KindPropertyAccessExpression {
43
+ return
44
+ }
45
+ outer := left.AsPropertyAccessExpression()
46
+ if outer == nil || identifierText(outer.Name()) != "length" {
47
+ return
48
+ }
49
+ receiver := stripParens(outer.Expression)
50
+ if receiver == nil || receiver.Kind != shimast.KindCallExpression {
51
+ return
52
+ }
53
+ call := receiver.AsCallExpression()
54
+ if call == nil || call.Expression == nil ||
55
+ call.Expression.Kind != shimast.KindPropertyAccessExpression {
56
+ return
57
+ }
58
+ access := call.Expression.AsPropertyAccessExpression()
59
+ if access == nil || identifierText(access.Name()) != "filter" {
60
+ return
61
+ }
62
+ ctx.Report(node, "Prefer `Array#some()` over `.filter(...).length > 0`.")
63
+ }
64
+
65
+ func init() {
66
+ Register(unicornPreferArraySome{})
67
+ }
@@ -0,0 +1,77 @@
1
+ // unicorn/prefer-at: `arr[arr.length - 1]` is the legacy spelling of
2
+ // "last element". ES2022 introduced `Array#at(-N)` (and `String#at(-N)`)
3
+ // which lets you reach for the same value from the tail without
4
+ // repeating the receiver and the subtraction. The rule pushes authors
5
+ // toward the built-in.
6
+ //
7
+ // AST-only: visit each `ElementAccessExpression`. The index expression
8
+ // must be a `BinaryExpression` whose operator is `-`, whose left side is
9
+ // `PropertyAccess(_, length)`, and whose right side is a positive
10
+ // numeric literal. The receiver of the `.length` access does not need
11
+ // to match the element-access receiver textually; mismatches are
12
+ // uncommon enough that the AST-only check stays useful in practice.
13
+ // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-at.md
14
+ package linthost
15
+
16
+ import shimast "github.com/microsoft/typescript-go/shim/ast"
17
+
18
+ type unicornPreferAt struct{}
19
+
20
+ func (unicornPreferAt) Name() string { return "unicorn/prefer-at" }
21
+ func (unicornPreferAt) Visits() []shimast.Kind {
22
+ return []shimast.Kind{shimast.KindElementAccessExpression}
23
+ }
24
+ func (unicornPreferAt) Check(ctx *Context, node *shimast.Node) {
25
+ access := node.AsElementAccessExpression()
26
+ if access == nil || access.ArgumentExpression == nil {
27
+ return
28
+ }
29
+ index := stripParens(access.ArgumentExpression)
30
+ if index == nil || index.Kind != shimast.KindBinaryExpression {
31
+ return
32
+ }
33
+ bin := index.AsBinaryExpression()
34
+ if bin == nil || bin.OperatorToken == nil ||
35
+ bin.OperatorToken.Kind != shimast.KindMinusToken {
36
+ return
37
+ }
38
+ left := stripParens(bin.Left)
39
+ if left == nil || left.Kind != shimast.KindPropertyAccessExpression {
40
+ return
41
+ }
42
+ prop := left.AsPropertyAccessExpression()
43
+ if prop == nil || identifierText(prop.Name()) != "length" {
44
+ return
45
+ }
46
+ right := stripParens(bin.Right)
47
+ if right == nil || right.Kind != shimast.KindNumericLiteral {
48
+ return
49
+ }
50
+ text := numericLiteralText(right)
51
+ if !unicornPreferAtIsPositiveInteger(text) {
52
+ return
53
+ }
54
+ ctx.Report(node, "Prefer `Array#at(-N)` / `String#at(-N)` over `arr[arr.length - N]`.")
55
+ }
56
+
57
+ // unicornPreferAtIsPositiveInteger reports whether `text` is the literal
58
+ // form of a positive integer (>= 1). Leading zeros are accepted because
59
+ // the JS scanner already normalized them; the only rejections are the
60
+ // empty string, plain `0`, and anything containing a non-digit (decimals,
61
+ // `e`-notation, hex, bigint suffix).
62
+ func unicornPreferAtIsPositiveInteger(text string) bool {
63
+ if text == "" || text == "0" {
64
+ return false
65
+ }
66
+ for i := 0; i < len(text); i++ {
67
+ c := text[i]
68
+ if c < '0' || c > '9' {
69
+ return false
70
+ }
71
+ }
72
+ return true
73
+ }
74
+
75
+ func init() {
76
+ Register(unicornPreferAt{})
77
+ }
@@ -0,0 +1,77 @@
1
+ // unicorn/prefer-bigint-literals: `BigInt(1)` and `BigInt("1")` both
2
+ // allocate a BigInt at runtime through a constructor call, while the
3
+ // equivalent `1n` literal is one parse-time token with no call
4
+ // overhead. The rule asks authors to use the literal form when the
5
+ // argument is a known integer.
6
+ //
7
+ // AST-only: visit `KindCallExpression`, fire when the callee is the
8
+ // bare `BigInt` identifier called with exactly one argument that is
9
+ // either a numeric literal of any shape, or a string literal whose
10
+ // content is a decimal-digit-only integer (optionally signed). The
11
+ // conservative string check avoids flagging `BigInt("0x10")` and
12
+ // other shapes that need a runtime parse.
13
+ //
14
+ // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-bigint-literals.md
15
+ package linthost
16
+
17
+ import shimast "github.com/microsoft/typescript-go/shim/ast"
18
+
19
+ type unicornPreferBigintLiterals struct{}
20
+
21
+ func (unicornPreferBigintLiterals) Name() string { return "unicorn/prefer-bigint-literals" }
22
+ func (unicornPreferBigintLiterals) Visits() []shimast.Kind {
23
+ return []shimast.Kind{shimast.KindCallExpression}
24
+ }
25
+ func (unicornPreferBigintLiterals) Check(ctx *Context, node *shimast.Node) {
26
+ call := node.AsCallExpression()
27
+ if call == nil || identifierText(call.Expression) != "BigInt" {
28
+ return
29
+ }
30
+ if call.Arguments == nil || len(call.Arguments.Nodes) != 1 {
31
+ return
32
+ }
33
+ arg := stripParens(call.Arguments.Nodes[0])
34
+ if arg == nil {
35
+ return
36
+ }
37
+ switch arg.Kind {
38
+ case shimast.KindNumericLiteral:
39
+ // `BigInt(1)` — always rewritable to `1n`.
40
+ case shimast.KindStringLiteral:
41
+ text := stringLiteralText(arg)
42
+ if !unicornPreferBigintLiteralsIsDecimalInteger(text) {
43
+ return
44
+ }
45
+ default:
46
+ return
47
+ }
48
+ ctx.Report(node, "Prefer BigInt literal `1n` over `BigInt(1)`.")
49
+ }
50
+
51
+ // unicornPreferBigintLiteralsIsDecimalInteger reports whether `text` is
52
+ // a non-empty decimal-integer literal — digits only, optional leading
53
+ // minus. The check is intentionally conservative; anything more exotic
54
+ // (hex prefix, exponent, decimal point) leaves the BigInt call alone.
55
+ func unicornPreferBigintLiteralsIsDecimalInteger(text string) bool {
56
+ if text == "" {
57
+ return false
58
+ }
59
+ i := 0
60
+ if text[0] == '-' || text[0] == '+' {
61
+ i++
62
+ }
63
+ if i == len(text) {
64
+ return false
65
+ }
66
+ for ; i < len(text); i++ {
67
+ ch := text[i]
68
+ if ch < '0' || ch > '9' {
69
+ return false
70
+ }
71
+ }
72
+ return true
73
+ }
74
+
75
+ func init() {
76
+ Register(unicornPreferBigintLiterals{})
77
+ }
@@ -0,0 +1,44 @@
1
+ // unicorn/prefer-blob-reading-methods: `FileReader#readAsArrayBuffer`
2
+ // and `FileReader#readAsText` predate the promise-returning `Blob`
3
+ // methods. They require attaching `load` / `error` listeners and reading
4
+ // `reader.result` in a callback, while `Blob#arrayBuffer()` and
5
+ // `Blob#text()` return a Promise that resolves to the same value
6
+ // directly. The newer shape is shorter, easier to reason about, and the
7
+ // rule discourages the legacy callback form.
8
+ //
9
+ // AST-only: visit each `CallExpression`, match a property-access callee
10
+ // whose method identifier is `readAsArrayBuffer` or `readAsText`, and
11
+ // fire on the call. The receiver is not type-checked — the syntactic
12
+ // shape is the signal regardless of whether the value is statically a
13
+ // `FileReader`.
14
+ // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-blob-reading-methods.md
15
+ package linthost
16
+
17
+ import shimast "github.com/microsoft/typescript-go/shim/ast"
18
+
19
+ type unicornPreferBlobReadingMethods struct{}
20
+
21
+ func (unicornPreferBlobReadingMethods) Name() string {
22
+ return "unicorn/prefer-blob-reading-methods"
23
+ }
24
+ func (unicornPreferBlobReadingMethods) Visits() []shimast.Kind {
25
+ return []shimast.Kind{shimast.KindCallExpression}
26
+ }
27
+ func (unicornPreferBlobReadingMethods) Check(ctx *Context, node *shimast.Node) {
28
+ call := node.AsCallExpression()
29
+ if call == nil || call.Expression == nil || call.Expression.Kind != shimast.KindPropertyAccessExpression {
30
+ return
31
+ }
32
+ access := call.Expression.AsPropertyAccessExpression()
33
+ if access == nil {
34
+ return
35
+ }
36
+ switch identifierText(access.Name()) {
37
+ case "readAsArrayBuffer", "readAsText":
38
+ ctx.Report(node, "Prefer `Blob#arrayBuffer()` / `Blob#text()` over `FileReader#readAsArrayBuffer` / `readAsText`.")
39
+ }
40
+ }
41
+
42
+ func init() {
43
+ Register(unicornPreferBlobReadingMethods{})
44
+ }
@@ -0,0 +1,93 @@
1
+ // unicorn/prefer-class-fields: assigning a primitive literal to
2
+ // `this.<field>` inside a class constructor is a TC39-era pattern that
3
+ // modern class-field declarations now express directly. The class-field
4
+ // form is shorter, makes the field visible at the class level without
5
+ // stepping through the constructor body, and avoids accidentally
6
+ // re-initializing a property that was already declared with a typed
7
+ // declaration.
8
+ //
9
+ // AST-only: visit `KindConstructor`. For each top-level statement in the
10
+ // constructor body, fire on any `ExpressionStatement` whose expression
11
+ // is an `=` `BinaryExpression` whose LHS is a property access on
12
+ // `this` and whose RHS is a primitive literal (`StringLiteral`,
13
+ // `NumericLiteral`, `KindTrueKeyword`, `KindFalseKeyword`,
14
+ // `KindNullKeyword`). The check is per-assignment, not per-constructor,
15
+ // so a constructor mixing several such assignments reports each one.
16
+ // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-class-fields.md
17
+ package linthost
18
+
19
+ import shimast "github.com/microsoft/typescript-go/shim/ast"
20
+
21
+ type unicornPreferClassFields struct{}
22
+
23
+ func (unicornPreferClassFields) Name() string { return "unicorn/prefer-class-fields" }
24
+ func (unicornPreferClassFields) Visits() []shimast.Kind {
25
+ return []shimast.Kind{shimast.KindConstructor}
26
+ }
27
+ func (unicornPreferClassFields) Check(ctx *Context, node *shimast.Node) {
28
+ ctor := node.AsConstructorDeclaration()
29
+ if ctor == nil || ctor.Body == nil {
30
+ return
31
+ }
32
+ body := ctor.Body.AsBlock()
33
+ if body == nil || body.Statements == nil {
34
+ return
35
+ }
36
+ for _, stmt := range body.Statements.Nodes {
37
+ if stmt == nil || stmt.Kind != shimast.KindExpressionStatement {
38
+ continue
39
+ }
40
+ exprStmt := stmt.AsExpressionStatement()
41
+ if exprStmt == nil || exprStmt.Expression == nil {
42
+ continue
43
+ }
44
+ expr := stripParens(exprStmt.Expression)
45
+ if expr == nil || expr.Kind != shimast.KindBinaryExpression {
46
+ continue
47
+ }
48
+ bin := expr.AsBinaryExpression()
49
+ if bin == nil || bin.OperatorToken == nil || bin.OperatorToken.Kind != shimast.KindEqualsToken {
50
+ continue
51
+ }
52
+ lhs := stripParens(bin.Left)
53
+ if lhs == nil || lhs.Kind != shimast.KindPropertyAccessExpression {
54
+ continue
55
+ }
56
+ access := lhs.AsPropertyAccessExpression()
57
+ if access == nil {
58
+ continue
59
+ }
60
+ receiver := stripParens(access.Expression)
61
+ if receiver == nil || receiver.Kind != shimast.KindThisKeyword {
62
+ continue
63
+ }
64
+ rhs := stripParens(bin.Right)
65
+ if !isPrimitiveLiteralForClassField(rhs) {
66
+ continue
67
+ }
68
+ ctx.Report(expr, "Prefer class field declarations over constructor assignments to `this.field`.")
69
+ }
70
+ }
71
+
72
+ // isPrimitiveLiteralForClassField reports whether `node` is one of the
73
+ // primitive-literal kinds that the prefer-class-fields rule treats as
74
+ // "trivially hoistable" to a class field initializer.
75
+ func isPrimitiveLiteralForClassField(node *shimast.Node) bool {
76
+ if node == nil {
77
+ return false
78
+ }
79
+ switch node.Kind {
80
+ case shimast.KindStringLiteral,
81
+ shimast.KindNumericLiteral,
82
+ shimast.KindTrueKeyword,
83
+ shimast.KindFalseKeyword,
84
+ shimast.KindNullKeyword,
85
+ shimast.KindNoSubstitutionTemplateLiteral:
86
+ return true
87
+ }
88
+ return false
89
+ }
90
+
91
+ func init() {
92
+ Register(unicornPreferClassFields{})
93
+ }
@@ -0,0 +1,120 @@
1
+ // unicorn/prefer-classlist-toggle: an `if (cond) el.classList.add(name)
2
+ // else el.classList.remove(name)` block can be collapsed into a single
3
+ // `el.classList.toggle(name, cond)` call. The toggle form is shorter,
4
+ // avoids accidental drift between the two branches, and matches the
5
+ // spec-blessed shape for conditional class management.
6
+ //
7
+ // AST-only minimum-viable port: visit `IfStatement` and match when both
8
+ // branches contain a single `ExpressionStatement` of
9
+ // `X.classList.add(arg)` and `X.classList.remove(arg)` (in either
10
+ // order), with identical receiver text on `X.classList` and identical
11
+ // argument text. Textual identity uses `nodeText` so this works without
12
+ // the Checker; receivers that differ at the type level but share their
13
+ // spelling will still match (the rule's signal is the syntactic shape
14
+ // of the two-branch toggle).
15
+ // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-classlist-toggle.md
16
+ package linthost
17
+
18
+ import shimast "github.com/microsoft/typescript-go/shim/ast"
19
+
20
+ type unicornPreferClasslistToggle struct{}
21
+
22
+ func (unicornPreferClasslistToggle) Name() string { return "unicorn/prefer-classlist-toggle" }
23
+ func (unicornPreferClasslistToggle) Visits() []shimast.Kind {
24
+ return []shimast.Kind{shimast.KindIfStatement}
25
+ }
26
+ func (unicornPreferClasslistToggle) Check(ctx *Context, node *shimast.Node) {
27
+ stmt := node.AsIfStatement()
28
+ if stmt == nil || stmt.ThenStatement == nil || stmt.ElseStatement == nil {
29
+ return
30
+ }
31
+ thenCall := classlistToggleSingleCall(stmt.ThenStatement)
32
+ elseCall := classlistToggleSingleCall(stmt.ElseStatement)
33
+ if thenCall == nil || elseCall == nil {
34
+ return
35
+ }
36
+ thenMethod, thenReceiver, thenArg := classlistAddRemoveParts(thenCall)
37
+ elseMethod, elseReceiver, elseArg := classlistAddRemoveParts(elseCall)
38
+ if thenMethod == "" || elseMethod == "" {
39
+ return
40
+ }
41
+ // One branch must be `add`, the other `remove` — order does not
42
+ // matter; the toggle rewrite is symmetric.
43
+ if !((thenMethod == "add" && elseMethod == "remove") ||
44
+ (thenMethod == "remove" && elseMethod == "add")) {
45
+ return
46
+ }
47
+ if nodeText(ctx.File, thenReceiver) != nodeText(ctx.File, elseReceiver) {
48
+ return
49
+ }
50
+ if nodeText(ctx.File, thenArg) != nodeText(ctx.File, elseArg) {
51
+ return
52
+ }
53
+ ctx.Report(node, "Prefer `classList.toggle(name, condition)` over manual `add`/`remove` branches.")
54
+ }
55
+
56
+ // classlistToggleSingleCall returns the single CallExpression inside a
57
+ // then/else branch — accepting either a bare ExpressionStatement or a
58
+ // Block wrapping exactly one ExpressionStatement. Returns nil for any
59
+ // other shape.
60
+ func classlistToggleSingleCall(branch *shimast.Node) *shimast.Node {
61
+ if branch == nil {
62
+ return nil
63
+ }
64
+ stmt := branch
65
+ if branch.Kind == shimast.KindBlock {
66
+ block := branch.AsBlock()
67
+ if block == nil || block.Statements == nil || len(block.Statements.Nodes) != 1 {
68
+ return nil
69
+ }
70
+ stmt = block.Statements.Nodes[0]
71
+ }
72
+ if stmt == nil || stmt.Kind != shimast.KindExpressionStatement {
73
+ return nil
74
+ }
75
+ expr := stmt.AsExpressionStatement()
76
+ if expr == nil || expr.Expression == nil {
77
+ return nil
78
+ }
79
+ call := stripParens(expr.Expression)
80
+ if call == nil || call.Kind != shimast.KindCallExpression {
81
+ return nil
82
+ }
83
+ return call
84
+ }
85
+
86
+ // classlistAddRemoveParts pulls (method, receiver, arg) out of a
87
+ // `X.classList.add(arg)` / `X.classList.remove(arg)` call, where
88
+ // `receiver` is the `X.classList` chain (the property-access expression
89
+ // node) and `arg` is the single argument. Returns ("", nil, nil) for
90
+ // any other shape.
91
+ func classlistAddRemoveParts(call *shimast.Node) (string, *shimast.Node, *shimast.Node) {
92
+ ce := call.AsCallExpression()
93
+ if ce == nil || ce.Expression == nil || ce.Arguments == nil || len(ce.Arguments.Nodes) != 1 {
94
+ return "", nil, nil
95
+ }
96
+ if ce.Expression.Kind != shimast.KindPropertyAccessExpression {
97
+ return "", nil, nil
98
+ }
99
+ access := ce.Expression.AsPropertyAccessExpression()
100
+ if access == nil {
101
+ return "", nil, nil
102
+ }
103
+ method := identifierText(access.Name())
104
+ if method != "add" && method != "remove" {
105
+ return "", nil, nil
106
+ }
107
+ receiver := access.Expression
108
+ if receiver == nil || receiver.Kind != shimast.KindPropertyAccessExpression {
109
+ return "", nil, nil
110
+ }
111
+ receiverAccess := receiver.AsPropertyAccessExpression()
112
+ if receiverAccess == nil || identifierText(receiverAccess.Name()) != "classList" {
113
+ return "", nil, nil
114
+ }
115
+ return method, receiver, ce.Arguments.Nodes[0]
116
+ }
117
+
118
+ func init() {
119
+ Register(unicornPreferClasslistToggle{})
120
+ }
@@ -0,0 +1,49 @@
1
+ // unicorn/prefer-code-point: `String#charCodeAt` and
2
+ // `String.fromCharCode` operate on UTF-16 code units, so they split
3
+ // astral characters (anything above U+FFFF) into surrogate pairs and
4
+ // return numbers that no longer correspond to the Unicode code point
5
+ // the source string visually shows. `String#codePointAt` and
6
+ // `String.fromCodePoint` operate on full code points and round-trip
7
+ // astral characters correctly.
8
+ //
9
+ // AST-only: visit `CallExpression`, match property-access callees whose
10
+ // method identifier is `charCodeAt` or `fromCharCode`. For
11
+ // `fromCharCode` also require the receiver to be the literal identifier
12
+ // `String` so we only flag the static `String.fromCharCode` form; for
13
+ // `charCodeAt` the receiver may be anything (any string instance).
14
+ // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-code-point.md
15
+ package linthost
16
+
17
+ import shimast "github.com/microsoft/typescript-go/shim/ast"
18
+
19
+ type unicornPreferCodePoint struct{}
20
+
21
+ func (unicornPreferCodePoint) Name() string { return "unicorn/prefer-code-point" }
22
+ func (unicornPreferCodePoint) Visits() []shimast.Kind {
23
+ return []shimast.Kind{shimast.KindCallExpression}
24
+ }
25
+ func (unicornPreferCodePoint) Check(ctx *Context, node *shimast.Node) {
26
+ call := node.AsCallExpression()
27
+ if call == nil || call.Expression == nil || call.Expression.Kind != shimast.KindPropertyAccessExpression {
28
+ return
29
+ }
30
+ access := call.Expression.AsPropertyAccessExpression()
31
+ if access == nil {
32
+ return
33
+ }
34
+ switch identifierText(access.Name()) {
35
+ case "charCodeAt":
36
+ // Instance call — receiver type is irrelevant.
37
+ ctx.Report(node, "Prefer `String#codePointAt()` / `String.fromCodePoint()` over `charCodeAt` / `fromCharCode`.")
38
+ case "fromCharCode":
39
+ // Static call — only the `String.fromCharCode(...)` shape.
40
+ if identifierText(access.Expression) != "String" {
41
+ return
42
+ }
43
+ ctx.Report(node, "Prefer `String#codePointAt()` / `String.fromCodePoint()` over `charCodeAt` / `fromCharCode`.")
44
+ }
45
+ }
46
+
47
+ func init() {
48
+ Register(unicornPreferCodePoint{})
49
+ }