@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,55 @@
1
+ // unicorn/no-useless-switch-case: a `case` clause with no statements
2
+ // that sits immediately above the `default` clause falls through to
3
+ // `default` for free — the value it matches would have hit `default`
4
+ // regardless. Keeping the empty case adds noise without changing the
5
+ // switch's behavior, so the rule reports it.
6
+ //
7
+ // AST-only: visit each `SwitchStatement`, walk its case-block clauses,
8
+ // and report any non-default `CaseClause` whose statements list is
9
+ // empty and whose immediate next sibling is the `DefaultClause`. The
10
+ // empty-body check distinguishes intentional grouped cases that share a
11
+ // non-trivial body from the redundant fall-into-default shape.
12
+ // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-useless-switch-case.md
13
+ package linthost
14
+
15
+ import shimast "github.com/microsoft/typescript-go/shim/ast"
16
+
17
+ type unicornNoUselessSwitchCase struct{}
18
+
19
+ func (unicornNoUselessSwitchCase) Name() string { return "unicorn/no-useless-switch-case" }
20
+ func (unicornNoUselessSwitchCase) Visits() []shimast.Kind {
21
+ return []shimast.Kind{shimast.KindSwitchStatement}
22
+ }
23
+ func (unicornNoUselessSwitchCase) Check(ctx *Context, node *shimast.Node) {
24
+ sw := node.AsSwitchStatement()
25
+ if sw == nil || sw.CaseBlock == nil {
26
+ return
27
+ }
28
+ block := sw.CaseBlock.AsCaseBlock()
29
+ if block == nil || block.Clauses == nil {
30
+ return
31
+ }
32
+ clauses := block.Clauses.Nodes
33
+ for i := 0; i < len(clauses)-1; i++ {
34
+ clause := clauses[i]
35
+ if clause == nil || clause.Kind != shimast.KindCaseClause {
36
+ continue
37
+ }
38
+ next := clauses[i+1]
39
+ if next == nil || next.Kind != shimast.KindDefaultClause {
40
+ continue
41
+ }
42
+ cd := clause.AsCaseOrDefaultClause()
43
+ if cd == nil {
44
+ continue
45
+ }
46
+ if cd.Statements != nil && len(cd.Statements.Nodes) != 0 {
47
+ continue
48
+ }
49
+ ctx.Report(clause, "Useless `case` clause — it falls through to the `default` which would handle this value anyway.")
50
+ }
51
+ }
52
+
53
+ func init() {
54
+ Register(unicornNoUselessSwitchCase{})
55
+ }
@@ -0,0 +1,55 @@
1
+ // unicorn/no-useless-undefined: `return undefined;` produces the same
2
+ // value as the bare `return;` form, and `void 0` is the canonical
3
+ // roundabout spelling of the same constant. Writing the keyword
4
+ // explicitly adds noise without changing behavior.
5
+ //
6
+ // Minimum-viable port: only the `return` statement shape fires. The
7
+ // call-argument case is intentionally skipped because matching it
8
+ // safely requires knowing which callees accept omission, and the
9
+ // parameter-default case (`function f(x = undefined)`) is deferred.
10
+ //
11
+ // AST-only: visit each `ReturnStatement` whose expression after
12
+ // `stripParens` is either the `undefined` keyword/identifier or the
13
+ // `void 0` shape (a `VoidExpression` whose operand is the numeric
14
+ // literal `0`). Reports on the return statement itself so the
15
+ // diagnostic anchors on the keyword rather than the operand.
16
+ // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-useless-undefined.md
17
+ package linthost
18
+
19
+ import shimast "github.com/microsoft/typescript-go/shim/ast"
20
+
21
+ type unicornNoUselessUndefined struct{}
22
+
23
+ func (unicornNoUselessUndefined) Name() string { return "unicorn/no-useless-undefined" }
24
+ func (unicornNoUselessUndefined) Visits() []shimast.Kind {
25
+ return []shimast.Kind{shimast.KindReturnStatement}
26
+ }
27
+ func (unicornNoUselessUndefined) Check(ctx *Context, node *shimast.Node) {
28
+ ret := node.AsReturnStatement()
29
+ if ret == nil || ret.Expression == nil {
30
+ return
31
+ }
32
+ expr := stripParens(ret.Expression)
33
+ if expr == nil {
34
+ return
35
+ }
36
+ if expr.Kind == shimast.KindUndefinedKeyword || identifierText(expr) == "undefined" {
37
+ ctx.Report(node, "Don't `return undefined;` — `return undefined;` and bare `return;` have the same effect.")
38
+ return
39
+ }
40
+ if expr.Kind == shimast.KindVoidExpression {
41
+ void := expr.AsVoidExpression()
42
+ if void == nil || void.Expression == nil {
43
+ return
44
+ }
45
+ operand := stripParens(void.Expression)
46
+ if operand != nil && operand.Kind == shimast.KindNumericLiteral &&
47
+ numericLiteralText(operand) == "0" {
48
+ ctx.Report(node, "Don't `return undefined;` — `return undefined;` and bare `return;` have the same effect.")
49
+ }
50
+ }
51
+ }
52
+
53
+ func init() {
54
+ Register(unicornNoUselessUndefined{})
55
+ }
@@ -0,0 +1,52 @@
1
+ // unicorn/no-zero-fractions: numeric literals such as `1.0`, `1.`, and
2
+ // `.0` carry a redundant fractional component or a trailing dot whose
3
+ // only visual effect is to mislead the reader into thinking the value
4
+ // needs floating-point semantics. The rule rewrites the source pattern
5
+ // out by reporting on the literal node.
6
+ //
7
+ // AST-only: visit `KindNumericLiteral`, read the raw source text via
8
+ // `nodeText` so the parser-normalized `.Text` (which drops the trailing
9
+ // dot and zero-pad) doesn't mask the smell, and match three regular
10
+ // expressions covering the canonical shapes:
11
+ //
12
+ // - `1.0`, `1.00`, `-1.0e5` — fractional part is all zeros.
13
+ // - `1.` — trailing dot with no fractional digits.
14
+ // - `.0`, `-.0e3` — leading dot with an all-zero fractional part.
15
+ //
16
+ // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-zero-fractions.md
17
+ package linthost
18
+
19
+ import (
20
+ "regexp"
21
+ "strings"
22
+
23
+ shimast "github.com/microsoft/typescript-go/shim/ast"
24
+ )
25
+
26
+ var (
27
+ unicornNoZeroFractionsTrailingZero = regexp.MustCompile(`^-?\d+\.0+([eE][+-]?\d+)?$`)
28
+ unicornNoZeroFractionsTrailingDot = regexp.MustCompile(`^-?\d+\.$`)
29
+ unicornNoZeroFractionsLeadingDot = regexp.MustCompile(`^-?\.0+([eE][+-]?\d+)?$`)
30
+ )
31
+
32
+ type unicornNoZeroFractions struct{}
33
+
34
+ func (unicornNoZeroFractions) Name() string { return "unicorn/no-zero-fractions" }
35
+ func (unicornNoZeroFractions) Visits() []shimast.Kind {
36
+ return []shimast.Kind{shimast.KindNumericLiteral}
37
+ }
38
+ func (unicornNoZeroFractions) Check(ctx *Context, node *shimast.Node) {
39
+ source := strings.TrimSpace(nodeText(ctx.File, node))
40
+ if source == "" {
41
+ return
42
+ }
43
+ if unicornNoZeroFractionsTrailingZero.MatchString(source) ||
44
+ unicornNoZeroFractionsTrailingDot.MatchString(source) ||
45
+ unicornNoZeroFractionsLeadingDot.MatchString(source) {
46
+ ctx.Report(node, "Don't use a redundant `.0` fraction or trailing dot on a number literal.")
47
+ }
48
+ }
49
+
50
+ func init() {
51
+ Register(unicornNoZeroFractions{})
52
+ }
@@ -0,0 +1,69 @@
1
+ // unicorn/number-literal-case: hex / binary / octal numeric literals
2
+ // have a conventional canonical form — the radix prefix is lowercase
3
+ // (`0x`, `0b`, `0o`) while hex digits are uppercase (`0xFF`). Mixed-case
4
+ // alternatives (`0Xff`, `0xff`, `0xFf`, `0XFF`) read inconsistently and
5
+ // the rule normalizes the codebase by reporting every literal that
6
+ // isn't already canonical.
7
+ //
8
+ // AST-only: visit `KindNumericLiteral` and `KindBigIntLiteral`, read
9
+ // the raw source text via `nodeText` so the prefix and digit casing
10
+ // survive the parser's normalization, and report when the prefix letter
11
+ // is uppercase OR any hex digit is lowercase. Decimal literals lack a
12
+ // prefix and never fire.
13
+ //
14
+ // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/number-literal-case.md
15
+ package linthost
16
+
17
+ import (
18
+ "strings"
19
+
20
+ shimast "github.com/microsoft/typescript-go/shim/ast"
21
+ )
22
+
23
+ type unicornNumberLiteralCase struct{}
24
+
25
+ func (unicornNumberLiteralCase) Name() string { return "unicorn/number-literal-case" }
26
+ func (unicornNumberLiteralCase) Visits() []shimast.Kind {
27
+ return []shimast.Kind{shimast.KindNumericLiteral, shimast.KindBigIntLiteral}
28
+ }
29
+ func (unicornNumberLiteralCase) Check(ctx *Context, node *shimast.Node) {
30
+ source := strings.TrimSpace(nodeText(ctx.File, node))
31
+ if len(source) < 2 || source[0] != '0' {
32
+ return
33
+ }
34
+ prefix := source[1]
35
+ switch prefix {
36
+ case 'x', 'X':
37
+ if unicornNumberLiteralCaseHexNeedsFix(source, prefix) {
38
+ ctx.Report(node, "Number literals should use a lowercase prefix and uppercase digits — e.g. `0xFF` instead of `0xff`.")
39
+ }
40
+ case 'b', 'B', 'o', 'O':
41
+ // Binary / octal digits are 0-1 / 0-7; only the prefix letter
42
+ // can be in the wrong case.
43
+ if prefix == 'B' || prefix == 'O' {
44
+ ctx.Report(node, "Number literals should use a lowercase prefix and uppercase digits — e.g. `0xFF` instead of `0xff`.")
45
+ }
46
+ }
47
+ }
48
+
49
+ // unicornNumberLiteralCaseHexNeedsFix reports whether the hex literal's
50
+ // raw source text deviates from `0x` + uppercase digits. The trailing
51
+ // `n` of a hex bigint literal (`0xFFn`) is allowed.
52
+ func unicornNumberLiteralCaseHexNeedsFix(source string, prefix byte) bool {
53
+ if prefix != 'x' {
54
+ return true
55
+ }
56
+ digits := source[2:]
57
+ digits = strings.TrimSuffix(digits, "n")
58
+ for i := 0; i < len(digits); i++ {
59
+ ch := digits[i]
60
+ if ch >= 'a' && ch <= 'f' {
61
+ return true
62
+ }
63
+ }
64
+ return false
65
+ }
66
+
67
+ func init() {
68
+ Register(unicornNumberLiteralCase{})
69
+ }
@@ -0,0 +1,75 @@
1
+ // unicorn/numeric-separators-style: ES2021 numeric separators (`_`)
2
+ // only help readability when the grouping itself is conventional —
3
+ // thousands for decimal (`1_000_000`) and four-digit groups for hex /
4
+ // binary / octal (`0xFFFF_FFFF`). Off-by-one groupings (`1_2345`) read
5
+ // worse than the unseparated form. The rule fires when any literal
6
+ // already uses `_` but its groups don't match the canonical pattern.
7
+ //
8
+ // AST-only: visit `KindNumericLiteral`, read the raw source via
9
+ // `nodeText` so the underscores survive parser normalization, pick the
10
+ // canonical group size from the prefix (`0x`/`0X` → 4, `0b`/`0B` → 4,
11
+ // `0o`/`0O` → 4, anything else → 3), and reject any literal that
12
+ // contains an underscore but whose integer portion fails the
13
+ // canonical-grouping regex.
14
+ //
15
+ // Conservative MVP: only the integer portion is checked. Floats and
16
+ // scientific notation that contain `_` follow the decimal grouping
17
+ // rule applied to the leading integer digits.
18
+ //
19
+ // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/numeric-separators-style.md
20
+ package linthost
21
+
22
+ import (
23
+ "regexp"
24
+ "strings"
25
+
26
+ shimast "github.com/microsoft/typescript-go/shim/ast"
27
+ )
28
+
29
+ var (
30
+ unicornNumericSeparatorsDecimal = regexp.MustCompile(`^[0-9]{1,3}(_[0-9]{3})*$`)
31
+ unicornNumericSeparatorsRadix4 = regexp.MustCompile(`^[0-9A-Fa-f]{1,4}(_[0-9A-Fa-f]{4})*$`)
32
+ )
33
+
34
+ type unicornNumericSeparatorsStyle struct{}
35
+
36
+ func (unicornNumericSeparatorsStyle) Name() string { return "unicorn/numeric-separators-style" }
37
+ func (unicornNumericSeparatorsStyle) Visits() []shimast.Kind {
38
+ return []shimast.Kind{shimast.KindNumericLiteral, shimast.KindBigIntLiteral}
39
+ }
40
+ func (unicornNumericSeparatorsStyle) Check(ctx *Context, node *shimast.Node) {
41
+ source := strings.TrimSpace(nodeText(ctx.File, node))
42
+ if source == "" || !strings.Contains(source, "_") {
43
+ return
44
+ }
45
+ // Strip a trailing BigInt `n` so the digit-grouping regex doesn't see it.
46
+ source = strings.TrimSuffix(source, "n")
47
+
48
+ // Pick the integer portion and the canonical grouping pattern based
49
+ // on prefix; floats fall through to the decimal rule applied to the
50
+ // leading integer digits before the `.` or `e`/`E`.
51
+ integer := source
52
+ pattern := unicornNumericSeparatorsDecimal
53
+ if len(source) >= 2 && source[0] == '0' {
54
+ switch source[1] {
55
+ case 'x', 'X', 'b', 'B', 'o', 'O':
56
+ integer = source[2:]
57
+ pattern = unicornNumericSeparatorsRadix4
58
+ }
59
+ }
60
+ if pattern == unicornNumericSeparatorsDecimal {
61
+ if dot := strings.IndexAny(integer, ".eE"); dot >= 0 {
62
+ integer = integer[:dot]
63
+ }
64
+ }
65
+ if !strings.Contains(integer, "_") {
66
+ return
67
+ }
68
+ if !pattern.MatchString(integer) {
69
+ ctx.Report(node, "Use canonical separator grouping for numeric literals (3 digits for decimal, 4 for hex).")
70
+ }
71
+ }
72
+
73
+ func init() {
74
+ Register(unicornNumericSeparatorsStyle{})
75
+ }
@@ -0,0 +1,66 @@
1
+ // unicorn/prefer-add-event-listener: assigning a function to an
2
+ // `on*` DOM property (`el.onclick = …`) installs at most one handler
3
+ // — any prior assignment is silently overwritten. `addEventListener`
4
+ // composes: every listener that registers receives the event, and
5
+ // `removeEventListener` revokes exactly the listener that was added.
6
+ // The property-assignment form is therefore a fragile shape that the
7
+ // rule encourages replacing with the explicit listener API.
8
+ //
9
+ // AST-only: visit each `BinaryExpression`, restrict to `=` assignments
10
+ // whose LHS is a property access, and match property names that start
11
+ // with `on` followed by at least one lowercase letter (so unrelated
12
+ // names like `onnxruntime` or `onClickHandler` don't fire). The
13
+ // assignment node itself is reported so the diagnostic underlines the
14
+ // statement the reader needs to rewrite.
15
+ // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-add-event-listener.md
16
+ package linthost
17
+
18
+ import shimast "github.com/microsoft/typescript-go/shim/ast"
19
+
20
+ type unicornPreferAddEventListener struct{}
21
+
22
+ func (unicornPreferAddEventListener) Name() string { return "unicorn/prefer-add-event-listener" }
23
+ func (unicornPreferAddEventListener) Visits() []shimast.Kind {
24
+ return []shimast.Kind{shimast.KindBinaryExpression}
25
+ }
26
+ func (unicornPreferAddEventListener) Check(ctx *Context, node *shimast.Node) {
27
+ bin := node.AsBinaryExpression()
28
+ if bin == nil || bin.OperatorToken == nil {
29
+ return
30
+ }
31
+ if bin.OperatorToken.Kind != shimast.KindEqualsToken {
32
+ return
33
+ }
34
+ lhs := stripParens(bin.Left)
35
+ if lhs == nil || lhs.Kind != shimast.KindPropertyAccessExpression {
36
+ return
37
+ }
38
+ access := lhs.AsPropertyAccessExpression()
39
+ if access == nil {
40
+ return
41
+ }
42
+ name := identifierText(access.Name())
43
+ if !isUnicornOnEventName(name) {
44
+ return
45
+ }
46
+ ctx.Report(node, "Prefer `addEventListener` / `removeEventListener` over assigning to `on*` properties.")
47
+ }
48
+
49
+ // isUnicornOnEventName reports whether `name` is `on<lower>...` of at
50
+ // least 3 characters. The third-character lowercase gate prevents
51
+ // matches on `onClick`, `onnxruntime`, and other names that begin with
52
+ // `on` but are not DOM event handlers.
53
+ func isUnicornOnEventName(name string) bool {
54
+ if len(name) < 3 {
55
+ return false
56
+ }
57
+ if name[0] != 'o' || name[1] != 'n' {
58
+ return false
59
+ }
60
+ c := name[2]
61
+ return c >= 'a' && c <= 'z'
62
+ }
63
+
64
+ func init() {
65
+ Register(unicornPreferAddEventListener{})
66
+ }
@@ -0,0 +1,51 @@
1
+ // unicorn/prefer-array-find: `arr.filter(predicate)[0]` walks the full
2
+ // array and allocates an intermediate result just to discard everything
3
+ // after the first match. `arr.find(predicate)` returns the same value
4
+ // without the wasted work and reads as the actual intent.
5
+ //
6
+ // AST-only: visit each `ElementAccessExpression`. The receiver must be a
7
+ // `CallExpression` whose callee is a `PropertyAccess(_, filter)` and the
8
+ // index argument must be the numeric literal `0`. Reports on the element
9
+ // access so editors highlight the whole `.filter(...)[0]` chain.
10
+ // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-array-find.md
11
+ package linthost
12
+
13
+ import shimast "github.com/microsoft/typescript-go/shim/ast"
14
+
15
+ type unicornPreferArrayFind struct{}
16
+
17
+ func (unicornPreferArrayFind) Name() string { return "unicorn/prefer-array-find" }
18
+ func (unicornPreferArrayFind) Visits() []shimast.Kind {
19
+ return []shimast.Kind{shimast.KindElementAccessExpression}
20
+ }
21
+ func (unicornPreferArrayFind) Check(ctx *Context, node *shimast.Node) {
22
+ access := node.AsElementAccessExpression()
23
+ if access == nil || access.Expression == nil || access.ArgumentExpression == nil {
24
+ return
25
+ }
26
+ index := stripParens(access.ArgumentExpression)
27
+ if index == nil || index.Kind != shimast.KindNumericLiteral {
28
+ return
29
+ }
30
+ if numericLiteralText(index) != "0" {
31
+ return
32
+ }
33
+ receiver := stripParens(access.Expression)
34
+ if receiver == nil || receiver.Kind != shimast.KindCallExpression {
35
+ return
36
+ }
37
+ call := receiver.AsCallExpression()
38
+ if call == nil || call.Expression == nil ||
39
+ call.Expression.Kind != shimast.KindPropertyAccessExpression {
40
+ return
41
+ }
42
+ prop := call.Expression.AsPropertyAccessExpression()
43
+ if prop == nil || identifierText(prop.Name()) != "filter" {
44
+ return
45
+ }
46
+ ctx.Report(node, "Prefer `Array#find()` over `Array#filter(...)[0]`.")
47
+ }
48
+
49
+ func init() {
50
+ Register(unicornPreferArrayFind{})
51
+ }
@@ -0,0 +1,52 @@
1
+ // unicorn/prefer-array-flat: `[].concat(a, b, c)` is the legacy flatten
2
+ // idiom — it works because `Array#concat` spreads array arguments — but
3
+ // it loses readability the moment a non-array sneaks into the argument
4
+ // list (it then gets pushed in as a single element instead of being
5
+ // flattened). `Array#flat()` has stable, type-aware semantics and is the
6
+ // supported one-line equivalent.
7
+ //
8
+ // AST-only: visit each `CallExpression`, match a property-access callee
9
+ // whose receiver is an empty array-literal expression and whose method
10
+ // identifier is `concat`, and fire when at least one argument is
11
+ // supplied. The empty-array receiver gate is what isolates the
12
+ // flattening idiom from ordinary `.concat()` usage on real arrays.
13
+ // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-array-flat.md
14
+ package linthost
15
+
16
+ import shimast "github.com/microsoft/typescript-go/shim/ast"
17
+
18
+ type unicornPreferArrayFlat struct{}
19
+
20
+ func (unicornPreferArrayFlat) Name() string { return "unicorn/prefer-array-flat" }
21
+ func (unicornPreferArrayFlat) Visits() []shimast.Kind {
22
+ return []shimast.Kind{shimast.KindCallExpression}
23
+ }
24
+ func (unicornPreferArrayFlat) Check(ctx *Context, node *shimast.Node) {
25
+ call := node.AsCallExpression()
26
+ if call == nil || call.Expression == nil || call.Expression.Kind != shimast.KindPropertyAccessExpression {
27
+ return
28
+ }
29
+ access := call.Expression.AsPropertyAccessExpression()
30
+ if access == nil {
31
+ return
32
+ }
33
+ if identifierText(access.Name()) != "concat" {
34
+ return
35
+ }
36
+ receiver := stripParens(access.Expression)
37
+ if receiver == nil || receiver.Kind != shimast.KindArrayLiteralExpression {
38
+ return
39
+ }
40
+ arr := receiver.AsArrayLiteralExpression()
41
+ if arr == nil || arr.Elements == nil || len(arr.Elements.Nodes) != 0 {
42
+ return
43
+ }
44
+ if call.Arguments == nil || len(call.Arguments.Nodes) == 0 {
45
+ return
46
+ }
47
+ ctx.Report(node, "Prefer `Array#flat()` over `[].concat(...arrays)`.")
48
+ }
49
+
50
+ func init() {
51
+ Register(unicornPreferArrayFlat{})
52
+ }
@@ -0,0 +1,63 @@
1
+ // unicorn/prefer-array-flat-map: the pair `someArr.map(fn).flat()` walks
2
+ // the source array twice — once to map and once to flatten — when a
3
+ // single `flatMap` call would do both in one pass. The rule flags the
4
+ // chained shape so authors collapse it to the built-in.
5
+ //
6
+ // AST-only: a `CallExpression` whose callee is `.flat` AND whose
7
+ // receiver is itself a `CallExpression` whose callee is `.map` matches.
8
+ // The `.flat(...)` call must be argument-less or explicitly `.flat(1)`
9
+ // — `.map(fn).flat(2)` is NOT equivalent to `.flatMap(fn)` because the
10
+ // latter only flattens one level. The diagnostic anchors on the outer
11
+ // call so editors highlight the whole `.map(...).flat(...)` chain.
12
+ // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-array-flat-map.md
13
+ package linthost
14
+
15
+ import shimast "github.com/microsoft/typescript-go/shim/ast"
16
+
17
+ type unicornPreferArrayFlatMap struct{}
18
+
19
+ func (unicornPreferArrayFlatMap) Name() string { return "unicorn/prefer-array-flat-map" }
20
+ func (unicornPreferArrayFlatMap) Visits() []shimast.Kind {
21
+ return []shimast.Kind{shimast.KindCallExpression}
22
+ }
23
+ func (unicornPreferArrayFlatMap) Check(ctx *Context, node *shimast.Node) {
24
+ call := node.AsCallExpression()
25
+ if call == nil || call.Expression == nil ||
26
+ call.Expression.Kind != shimast.KindPropertyAccessExpression {
27
+ return
28
+ }
29
+ outerAccess := call.Expression.AsPropertyAccessExpression()
30
+ if outerAccess == nil || identifierText(outerAccess.Name()) != "flat" {
31
+ return
32
+ }
33
+ // `.flat(2)` and deeper are NOT equivalent to `.flatMap` — only the
34
+ // default depth (no arg) or explicit depth 1 collapse cleanly.
35
+ if call.Arguments != nil && len(call.Arguments.Nodes) > 0 {
36
+ if len(call.Arguments.Nodes) != 1 {
37
+ return
38
+ }
39
+ arg := stripParens(call.Arguments.Nodes[0])
40
+ if arg == nil || arg.Kind != shimast.KindNumericLiteral ||
41
+ numericLiteralText(arg) != "1" {
42
+ return
43
+ }
44
+ }
45
+ receiver := stripParens(outerAccess.Expression)
46
+ if receiver == nil || receiver.Kind != shimast.KindCallExpression {
47
+ return
48
+ }
49
+ innerCall := receiver.AsCallExpression()
50
+ if innerCall == nil || innerCall.Expression == nil ||
51
+ innerCall.Expression.Kind != shimast.KindPropertyAccessExpression {
52
+ return
53
+ }
54
+ innerAccess := innerCall.Expression.AsPropertyAccessExpression()
55
+ if innerAccess == nil || identifierText(innerAccess.Name()) != "map" {
56
+ return
57
+ }
58
+ ctx.Report(node, "Prefer `Array#flatMap` over `Array#map().flat()`.")
59
+ }
60
+
61
+ func init() {
62
+ Register(unicornPreferArrayFlatMap{})
63
+ }