@ttsc/lint 0.13.0 → 0.14.0-dev.20250530.1

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 (498) hide show
  1. package/README.md +955 -85
  2. package/lib/defaultFormat.d.ts +15 -8
  3. package/lib/defaultFormat.js +15 -8
  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/TtscLintRuleSetting.d.ts +49 -0
  10. package/lib/structures/{TtscLintRuleOptions.js → TtscLintRuleSetting.js} +1 -1
  11. package/lib/structures/TtscLintRuleSetting.js.map +1 -0
  12. package/lib/structures/format/ITtscLintFormat.d.ts +128 -0
  13. package/lib/structures/{TtscLintRuleMap.js → format/ITtscLintFormat.js} +1 -1
  14. package/lib/structures/format/ITtscLintFormat.js.map +1 -0
  15. package/lib/structures/format/ITtscLintFormatJsDoc.d.ts +17 -0
  16. package/lib/structures/{ITtscLintFormatConfig.js → format/ITtscLintFormatJsDoc.js} +1 -1
  17. package/lib/structures/format/ITtscLintFormatJsDoc.js.map +1 -0
  18. package/lib/structures/format/ITtscLintFormatSortImports.d.ts +54 -0
  19. package/lib/structures/format/ITtscLintFormatSortImports.js +3 -0
  20. package/lib/structures/format/ITtscLintFormatSortImports.js.map +1 -0
  21. package/lib/structures/format/index.d.ts +3 -0
  22. package/lib/structures/format/index.js +20 -0
  23. package/lib/structures/format/index.js.map +1 -0
  24. package/lib/structures/index.d.ts +3 -4
  25. package/lib/structures/index.js +3 -4
  26. package/lib/structures/index.js.map +1 -1
  27. package/lib/structures/rules/ITtscLintBoundariesRuleOptions.d.ts +95 -0
  28. package/lib/structures/rules/ITtscLintBoundariesRuleOptions.js +13 -0
  29. package/lib/structures/rules/ITtscLintBoundariesRuleOptions.js.map +1 -0
  30. package/lib/structures/rules/ITtscLintBoundariesRules.d.ts +75 -0
  31. package/lib/structures/rules/ITtscLintBoundariesRules.js +3 -0
  32. package/lib/structures/rules/ITtscLintBoundariesRules.js.map +1 -0
  33. package/lib/structures/rules/ITtscLintContributorRules.d.ts +16 -0
  34. package/lib/structures/rules/ITtscLintContributorRules.js +3 -0
  35. package/lib/structures/rules/ITtscLintContributorRules.js.map +1 -0
  36. package/lib/structures/rules/ITtscLintCoreRules.d.ts +1229 -0
  37. package/lib/structures/rules/ITtscLintCoreRules.js +3 -0
  38. package/lib/structures/rules/ITtscLintCoreRules.js.map +1 -0
  39. package/lib/structures/rules/ITtscLintCypressRuleOptions.d.ts +17 -0
  40. package/lib/structures/rules/ITtscLintCypressRuleOptions.js +10 -0
  41. package/lib/structures/rules/ITtscLintCypressRuleOptions.js.map +1 -0
  42. package/lib/structures/rules/ITtscLintCypressRules.d.ts +125 -0
  43. package/lib/structures/rules/ITtscLintCypressRules.js +3 -0
  44. package/lib/structures/rules/ITtscLintCypressRules.js.map +1 -0
  45. package/lib/structures/rules/ITtscLintFunctionalRuleOptions.d.ts +154 -0
  46. package/lib/structures/rules/ITtscLintFunctionalRuleOptions.js +13 -0
  47. package/lib/structures/rules/ITtscLintFunctionalRuleOptions.js.map +1 -0
  48. package/lib/structures/rules/ITtscLintFunctionalRules.d.ts +162 -0
  49. package/lib/structures/rules/ITtscLintFunctionalRules.js +3 -0
  50. package/lib/structures/rules/ITtscLintFunctionalRules.js.map +1 -0
  51. package/lib/structures/rules/ITtscLintJestRules.d.ts +190 -0
  52. package/lib/structures/rules/ITtscLintJestRules.js +3 -0
  53. package/lib/structures/rules/ITtscLintJestRules.js.map +1 -0
  54. package/lib/structures/rules/ITtscLintJsdocRules.d.ts +133 -0
  55. package/lib/structures/rules/ITtscLintJsdocRules.js +3 -0
  56. package/lib/structures/rules/ITtscLintJsdocRules.js.map +1 -0
  57. package/lib/structures/rules/ITtscLintJsxA11yRules.d.ts +294 -0
  58. package/lib/structures/rules/ITtscLintJsxA11yRules.js +3 -0
  59. package/lib/structures/rules/ITtscLintJsxA11yRules.js.map +1 -0
  60. package/lib/structures/rules/ITtscLintNextjsRules.d.ts +180 -0
  61. package/lib/structures/rules/ITtscLintNextjsRules.js +3 -0
  62. package/lib/structures/rules/ITtscLintNextjsRules.js.map +1 -0
  63. package/lib/structures/rules/ITtscLintPlaywrightRules.d.ts +312 -0
  64. package/lib/structures/rules/ITtscLintPlaywrightRules.js +3 -0
  65. package/lib/structures/rules/ITtscLintPlaywrightRules.js.map +1 -0
  66. package/lib/structures/rules/ITtscLintPromiseRules.d.ts +179 -0
  67. package/lib/structures/rules/ITtscLintPromiseRules.js +3 -0
  68. package/lib/structures/rules/ITtscLintPromiseRules.js.map +1 -0
  69. package/lib/structures/rules/ITtscLintReactPerfRuleOptions.d.ts +18 -0
  70. package/lib/structures/rules/ITtscLintReactPerfRuleOptions.js +8 -0
  71. package/lib/structures/rules/ITtscLintReactPerfRuleOptions.js.map +1 -0
  72. package/lib/structures/rules/ITtscLintReactPerfRules.d.ts +49 -0
  73. package/lib/structures/rules/ITtscLintReactPerfRules.js +3 -0
  74. package/lib/structures/rules/ITtscLintReactPerfRules.js.map +1 -0
  75. package/lib/structures/rules/ITtscLintReactRuleOptions.d.ts +37 -0
  76. package/lib/structures/rules/ITtscLintReactRuleOptions.js +11 -0
  77. package/lib/structures/rules/ITtscLintReactRuleOptions.js.map +1 -0
  78. package/lib/structures/rules/ITtscLintReactRules.d.ts +276 -0
  79. package/lib/structures/rules/ITtscLintReactRules.js +3 -0
  80. package/lib/structures/rules/ITtscLintReactRules.js.map +1 -0
  81. package/lib/structures/rules/ITtscLintRegexpRules.d.ts +182 -0
  82. package/lib/structures/rules/ITtscLintRegexpRules.js +3 -0
  83. package/lib/structures/rules/ITtscLintRegexpRules.js.map +1 -0
  84. package/lib/structures/rules/ITtscLintRuleOptionsMap.d.ts +65 -0
  85. package/lib/structures/rules/ITtscLintRuleOptionsMap.js +3 -0
  86. package/lib/structures/rules/ITtscLintRuleOptionsMap.js.map +1 -0
  87. package/lib/structures/rules/ITtscLintRules.d.ts +55 -0
  88. package/lib/structures/{TtscLintRule.js → rules/ITtscLintRules.js} +1 -1
  89. package/lib/structures/rules/ITtscLintRules.js.map +1 -0
  90. package/lib/structures/rules/ITtscLintSecurityRules.d.ts +141 -0
  91. package/lib/structures/rules/ITtscLintSecurityRules.js +3 -0
  92. package/lib/structures/rules/ITtscLintSecurityRules.js.map +1 -0
  93. package/lib/structures/rules/ITtscLintSolidRules.d.ts +178 -0
  94. package/lib/structures/rules/ITtscLintSolidRules.js +3 -0
  95. package/lib/structures/rules/ITtscLintSolidRules.js.map +1 -0
  96. package/lib/structures/rules/ITtscLintStorybookRuleOptions.d.ts +20 -0
  97. package/lib/structures/rules/ITtscLintStorybookRuleOptions.js +9 -0
  98. package/lib/structures/rules/ITtscLintStorybookRuleOptions.js.map +1 -0
  99. package/lib/structures/rules/ITtscLintStorybookRules.d.ts +165 -0
  100. package/lib/structures/rules/ITtscLintStorybookRules.js +3 -0
  101. package/lib/structures/rules/ITtscLintStorybookRules.js.map +1 -0
  102. package/lib/structures/rules/ITtscLintTanstackQueryRules.d.ts +88 -0
  103. package/lib/structures/rules/ITtscLintTanstackQueryRules.js +3 -0
  104. package/lib/structures/rules/ITtscLintTanstackQueryRules.js.map +1 -0
  105. package/lib/structures/rules/ITtscLintTestingLibraryRuleOptions.d.ts +21 -0
  106. package/lib/structures/rules/ITtscLintTestingLibraryRuleOptions.js +10 -0
  107. package/lib/structures/rules/ITtscLintTestingLibraryRuleOptions.js.map +1 -0
  108. package/lib/structures/rules/ITtscLintTestingLibraryRules.d.ts +293 -0
  109. package/lib/structures/rules/ITtscLintTestingLibraryRules.js +3 -0
  110. package/lib/structures/rules/ITtscLintTestingLibraryRules.js.map +1 -0
  111. package/lib/structures/rules/ITtscLintTypeScriptRules.d.ts +1074 -0
  112. package/lib/structures/rules/ITtscLintTypeScriptRules.js +3 -0
  113. package/lib/structures/rules/ITtscLintTypeScriptRules.js.map +1 -0
  114. package/lib/structures/rules/ITtscLintUnicornRules.d.ts +997 -0
  115. package/lib/structures/rules/ITtscLintUnicornRules.js +3 -0
  116. package/lib/structures/rules/ITtscLintUnicornRules.js.map +1 -0
  117. package/lib/structures/rules/ITtscLintVitestRules.d.ts +133 -0
  118. package/lib/structures/rules/ITtscLintVitestRules.js +3 -0
  119. package/lib/structures/rules/ITtscLintVitestRules.js.map +1 -0
  120. package/lib/structures/rules/index.d.ts +31 -0
  121. package/lib/structures/rules/index.js +48 -0
  122. package/lib/structures/rules/index.js.map +1 -0
  123. package/linthost/ast_helpers.go +30 -5
  124. package/linthost/compile.go +33 -2
  125. package/linthost/config.go +118 -71
  126. package/linthost/config_format.go +270 -104
  127. package/linthost/directives.go +67 -25
  128. package/linthost/dispatch.go +14 -3
  129. package/linthost/engine.go +160 -40
  130. package/linthost/fix.go +10 -3
  131. package/linthost/flags_gen.go +17 -15
  132. package/linthost/format.go +222 -25
  133. package/linthost/format_editor_settings.go +262 -0
  134. package/linthost/host.go +40 -3
  135. package/linthost/lsp.go +898 -0
  136. package/linthost/print_dispatch.go +5 -2
  137. package/linthost/print_engine.go +5 -5
  138. package/linthost/print_nodes_call.go +149 -67
  139. package/linthost/print_nodes_function.go +27 -2
  140. package/linthost/print_nodes_list.go +40 -5
  141. package/linthost/print_nodes_object.go +1 -1
  142. package/linthost/print_nodes_ternary.go +86 -0
  143. package/linthost/rule_names.go +14 -0
  144. package/linthost/rules_arrays.go +2 -2
  145. package/linthost/rules_boundaries.go +532 -0
  146. package/linthost/rules_camelcase.go +133 -0
  147. package/linthost/rules_complexity.go +95 -0
  148. package/linthost/rules_consistent_return.go +130 -0
  149. package/linthost/rules_console.go +1 -1
  150. package/linthost/rules_core_extra.go +739 -0
  151. package/linthost/rules_curly.go +70 -0
  152. package/linthost/rules_cypress.go +608 -0
  153. package/linthost/rules_debugger.go +2 -2
  154. package/linthost/rules_default_case.go +39 -0
  155. package/linthost/rules_default_case_last.go +46 -0
  156. package/linthost/rules_dupes.go +3 -3
  157. package/linthost/rules_empty.go +3 -3
  158. package/linthost/rules_escape.go +44 -24
  159. package/linthost/rules_eval.go +2 -2
  160. package/linthost/rules_finally.go +2 -2
  161. package/linthost/rules_format_arrow_parens.go +167 -0
  162. package/linthost/rules_format_bracket_spacing.go +117 -0
  163. package/linthost/rules_format_clause_join.go +172 -0
  164. package/linthost/rules_format_declaration_header.go +595 -0
  165. package/linthost/rules_format_indent.go +372 -0
  166. package/linthost/rules_format_jsdoc.go +5 -5
  167. package/linthost/rules_format_orphan_semi.go +106 -0
  168. package/linthost/rules_format_parameter_properties.go +175 -0
  169. package/linthost/rules_format_print_width.go +66 -55
  170. package/linthost/rules_format_quote_props.go +169 -0
  171. package/linthost/rules_format_quotes.go +76 -30
  172. package/linthost/rules_format_semi.go +186 -11
  173. package/linthost/rules_format_sort_imports.go +437 -118
  174. package/linthost/rules_format_statement_split.go +343 -0
  175. package/linthost/rules_format_ternary_nullish_parens.go +77 -0
  176. package/linthost/rules_format_trailing_comma.go +22 -3
  177. package/linthost/rules_format_whitespace.go +336 -0
  178. package/linthost/rules_functional.go +967 -0
  179. package/linthost/rules_gap.go +24 -45
  180. package/linthost/rules_grouped_accessor_pairs.go +87 -0
  181. package/linthost/rules_guard_for_in.go +198 -0
  182. package/linthost/rules_id_length.go +77 -0
  183. package/linthost/rules_imports.go +70 -2
  184. package/linthost/rules_init_declarations.go +53 -0
  185. package/linthost/rules_jest.go +618 -0
  186. package/linthost/rules_jsdoc.go +502 -0
  187. package/linthost/rules_jsx_a11y.go +1264 -0
  188. package/linthost/rules_logic.go +12 -12
  189. package/linthost/rules_loops.go +1 -1
  190. package/linthost/rules_max_classes_per_file.go +58 -0
  191. package/linthost/rules_max_depth.go +83 -0
  192. package/linthost/rules_max_lines.go +101 -0
  193. package/linthost/rules_max_lines_per_function.go +57 -0
  194. package/linthost/rules_max_nested_callbacks.go +61 -0
  195. package/linthost/rules_max_params.go +49 -0
  196. package/linthost/rules_max_statements.go +59 -0
  197. package/linthost/rules_misc.go +1 -1
  198. package/linthost/rules_nextjs.go +697 -0
  199. package/linthost/rules_no_else_return.go +75 -0
  200. package/linthost/rules_no_empty_named_blocks.go +91 -0
  201. package/linthost/rules_no_extend_native.go +51 -0
  202. package/linthost/rules_no_import_assign.go +140 -0
  203. package/linthost/rules_no_invalid_this.go +52 -0
  204. package/linthost/rules_no_loop_func.go +85 -0
  205. package/linthost/rules_no_magic_numbers.go +123 -0
  206. package/linthost/rules_no_mixed_operators.go +80 -0
  207. package/linthost/rules_no_param_reassign.go +98 -0
  208. package/linthost/rules_no_redeclare.go +270 -0
  209. package/linthost/rules_no_restricted_imports.go +105 -0
  210. package/linthost/rules_no_restricted_syntax.go +49 -0
  211. package/linthost/rules_no_shadow.go +147 -0
  212. package/linthost/rules_no_unreachable.go +77 -0
  213. package/linthost/rules_no_useless_assignment.go +120 -0
  214. package/linthost/rules_no_useless_constructor.go +245 -0
  215. package/linthost/rules_no_useless_return.go +51 -0
  216. package/linthost/rules_params.go +1 -1
  217. package/linthost/rules_playwright.go +788 -0
  218. package/linthost/rules_prefer_arrow_callback.go +124 -0
  219. package/linthost/rules_prefer_destructuring.go +98 -0
  220. package/linthost/rules_prefer_named_capture_group.go +129 -0
  221. package/linthost/rules_prefer_rest_params.go +94 -0
  222. package/linthost/rules_problems.go +41 -30
  223. package/linthost/rules_promise.go +1057 -2
  224. package/linthost/rules_protos.go +2 -2
  225. package/linthost/rules_react.go +773 -0
  226. package/linthost/rules_react_extras.go +227 -0
  227. package/linthost/rules_react_hooks.go +848 -0
  228. package/linthost/rules_react_perf.go +293 -0
  229. package/linthost/rules_react_refresh.go +583 -0
  230. package/linthost/rules_regexp.go +410 -0
  231. package/linthost/rules_security.go +830 -0
  232. package/linthost/rules_self.go +2 -2
  233. package/linthost/rules_solid.go +1073 -0
  234. package/linthost/rules_sort_imports.go +69 -0
  235. package/linthost/rules_sort_keys.go +134 -0
  236. package/linthost/rules_storybook.go +1176 -0
  237. package/linthost/rules_strings.go +4 -4
  238. package/linthost/rules_suggestions.go +38 -38
  239. package/linthost/rules_tanstack_query.go +844 -0
  240. package/linthost/rules_testing_library.go +1204 -0
  241. package/linthost/rules_throw.go +1 -1
  242. package/linthost/rules_ts.go +19 -19
  243. package/linthost/rules_ts_async.go +399 -0
  244. package/linthost/rules_ts_class_literal_property_style.go +115 -0
  245. package/linthost/rules_ts_consistent_type_exports.go +256 -0
  246. package/linthost/rules_ts_explicit_function_return_type.go +67 -0
  247. package/linthost/rules_ts_extra.go +159 -36
  248. package/linthost/rules_ts_no_base_to_string.go +218 -0
  249. package/linthost/rules_ts_no_confusing_void.go +72 -0
  250. package/linthost/rules_ts_no_deprecated.go +195 -0
  251. package/linthost/rules_ts_no_for_in_array.go +84 -0
  252. package/linthost/rules_ts_no_magic_numbers.go +124 -0
  253. package/linthost/rules_ts_no_meaningless_void_operator.go +84 -0
  254. package/linthost/rules_ts_no_misused_spread.go +104 -0
  255. package/linthost/rules_ts_no_redundant_type_constituents.go +113 -0
  256. package/linthost/rules_ts_no_restricted_types.go +62 -0
  257. package/linthost/rules_ts_no_unnecessary_boolean_literal_compare.go +129 -0
  258. package/linthost/rules_ts_no_unnecessary_condition.go +250 -0
  259. package/linthost/rules_ts_no_unnecessary_qualifier.go +118 -0
  260. package/linthost/rules_ts_no_unnecessary_template_expression.go +178 -0
  261. package/linthost/rules_ts_no_unnecessary_type_arguments.go +234 -0
  262. package/linthost/rules_ts_no_unnecessary_type_assertion.go +157 -0
  263. package/linthost/rules_ts_no_unsafe_argument.go +82 -0
  264. package/linthost/rules_ts_no_unsafe_assignment.go +102 -0
  265. package/linthost/rules_ts_no_unsafe_call.go +82 -0
  266. package/linthost/rules_ts_no_unsafe_enum_comparison.go +235 -0
  267. package/linthost/rules_ts_no_unsafe_member_access.go +58 -0
  268. package/linthost/rules_ts_no_unsafe_return.go +126 -0
  269. package/linthost/rules_ts_no_unsafe_unary_minus.go +81 -0
  270. package/linthost/rules_ts_no_useless_constructor.go +52 -0
  271. package/linthost/rules_ts_non_nullable_type_assertion_style.go +108 -0
  272. package/linthost/rules_ts_parameter_properties.go +38 -0
  273. package/linthost/rules_ts_prefer_find.go +178 -0
  274. package/linthost/rules_ts_prefer_includes.go +255 -0
  275. package/linthost/rules_ts_prefer_nullish_coalescing.go +104 -0
  276. package/linthost/rules_ts_prefer_optional_chain.go +228 -0
  277. package/linthost/rules_ts_prefer_promise_reject_errors.go +176 -0
  278. package/linthost/rules_ts_prefer_readonly.go +73 -0
  279. package/linthost/rules_ts_prefer_reduce_type_parameter.go +116 -0
  280. package/linthost/rules_ts_prefer_regexp_exec.go +122 -0
  281. package/linthost/rules_ts_prefer_return_this_type.go +135 -0
  282. package/linthost/rules_ts_prefer_string_starts_ends_with.go +360 -0
  283. package/linthost/rules_ts_promise_function_async.go +77 -0
  284. package/linthost/rules_ts_related_getter_setter_pairs.go +113 -0
  285. package/linthost/rules_ts_require_array_sort_compare.go +96 -0
  286. package/linthost/rules_ts_restrict_plus_operands.go +127 -0
  287. package/linthost/rules_ts_restrict_template_expressions.go +95 -0
  288. package/linthost/rules_ts_simple.go +387 -0
  289. package/linthost/rules_ts_sort_type_constituents.go +144 -0
  290. package/linthost/rules_ts_strict_boolean_expressions.go +157 -0
  291. package/linthost/rules_ts_switch_exhaustiveness_check.go +147 -0
  292. package/linthost/rules_ts_unbound_method.go +126 -0
  293. package/linthost/rules_tsdoc.go +136 -0
  294. package/linthost/rules_unicorn_better_regex.go +27 -0
  295. package/linthost/rules_unicorn_catch_error_name.go +46 -0
  296. package/linthost/rules_unicorn_consistent_assert.go +47 -0
  297. package/linthost/rules_unicorn_consistent_date_clone.go +54 -0
  298. package/linthost/rules_unicorn_consistent_destructuring.go +25 -0
  299. package/linthost/rules_unicorn_consistent_empty_array_spread.go +62 -0
  300. package/linthost/rules_unicorn_consistent_existence_index_check.go +80 -0
  301. package/linthost/rules_unicorn_consistent_function_scoping.go +25 -0
  302. package/linthost/rules_unicorn_consistent_template_literal_escape.go +25 -0
  303. package/linthost/rules_unicorn_custom_error_definition.go +138 -0
  304. package/linthost/rules_unicorn_empty_brace_spaces.go +73 -0
  305. package/linthost/rules_unicorn_error_message.go +64 -0
  306. package/linthost/rules_unicorn_escape_case.go +51 -0
  307. package/linthost/rules_unicorn_expiring_todo_comments.go +78 -0
  308. package/linthost/rules_unicorn_explicit_length_check.go +88 -0
  309. package/linthost/rules_unicorn_filename_case.go +29 -0
  310. package/linthost/rules_unicorn_import_style.go +28 -0
  311. package/linthost/rules_unicorn_isolated_functions.go +29 -0
  312. package/linthost/rules_unicorn_new_for_builtins.go +87 -0
  313. package/linthost/rules_unicorn_no_abusive_eslint_disable.go +63 -0
  314. package/linthost/rules_unicorn_no_accessor_recursion.go +115 -0
  315. package/linthost/rules_unicorn_no_anonymous_default_export.go +74 -0
  316. package/linthost/rules_unicorn_no_array_callback_reference.go +65 -0
  317. package/linthost/rules_unicorn_no_array_for_each.go +40 -0
  318. package/linthost/rules_unicorn_no_array_method_this_argument.go +61 -0
  319. package/linthost/rules_unicorn_no_array_reduce.go +41 -0
  320. package/linthost/rules_unicorn_no_array_reverse.go +44 -0
  321. package/linthost/rules_unicorn_no_array_sort.go +43 -0
  322. package/linthost/rules_unicorn_no_await_expression_member.go +40 -0
  323. package/linthost/rules_unicorn_no_await_in_promise_methods.go +69 -0
  324. package/linthost/rules_unicorn_no_console_spaces.go +61 -0
  325. package/linthost/rules_unicorn_no_document_cookie.go +41 -0
  326. package/linthost/rules_unicorn_no_empty_file.go +44 -0
  327. package/linthost/rules_unicorn_no_for_loop.go +102 -0
  328. package/linthost/rules_unicorn_no_hex_escape.go +42 -0
  329. package/linthost/rules_unicorn_no_immediate_mutation.go +90 -0
  330. package/linthost/rules_unicorn_no_instanceof_builtins.go +66 -0
  331. package/linthost/rules_unicorn_no_invalid_fetch_options.go +79 -0
  332. package/linthost/rules_unicorn_no_invalid_remove_event_listener.go +51 -0
  333. package/linthost/rules_unicorn_no_keyword_prefix.go +101 -0
  334. package/linthost/rules_unicorn_no_lonely_if.go +44 -0
  335. package/linthost/rules_unicorn_no_magic_array_flat_depth.go +51 -0
  336. package/linthost/rules_unicorn_no_named_default.go +54 -0
  337. package/linthost/rules_unicorn_no_negated_condition.go +85 -0
  338. package/linthost/rules_unicorn_no_negation_in_equality_check.go +50 -0
  339. package/linthost/rules_unicorn_no_nested_ternary.go +43 -0
  340. package/linthost/rules_unicorn_no_new_array.go +30 -0
  341. package/linthost/rules_unicorn_no_new_buffer.go +31 -0
  342. package/linthost/rules_unicorn_no_null.go +24 -0
  343. package/linthost/rules_unicorn_no_object_as_default_parameter.go +48 -0
  344. package/linthost/rules_unicorn_no_process_exit.go +43 -0
  345. package/linthost/rules_unicorn_no_single_promise_in_promise_methods.go +59 -0
  346. package/linthost/rules_unicorn_no_static_only_class.go +56 -0
  347. package/linthost/rules_unicorn_no_thenable.go +74 -0
  348. package/linthost/rules_unicorn_no_this_assignment.go +35 -0
  349. package/linthost/rules_unicorn_no_typeof_undefined.go +58 -0
  350. package/linthost/rules_unicorn_no_unnecessary_array_flat_depth.go +49 -0
  351. package/linthost/rules_unicorn_no_unnecessary_array_splice_count.go +70 -0
  352. package/linthost/rules_unicorn_no_unnecessary_await.go +51 -0
  353. package/linthost/rules_unicorn_no_unnecessary_polyfills.go +32 -0
  354. package/linthost/rules_unicorn_no_unnecessary_slice_end.go +48 -0
  355. package/linthost/rules_unicorn_no_unreadable_array_destructuring.go +115 -0
  356. package/linthost/rules_unicorn_no_unreadable_iife.go +50 -0
  357. package/linthost/rules_unicorn_no_unused_properties.go +30 -0
  358. package/linthost/rules_unicorn_no_useless_collection_argument.go +63 -0
  359. package/linthost/rules_unicorn_no_useless_error_capture_stack_trace.go +46 -0
  360. package/linthost/rules_unicorn_no_useless_fallback_in_spread.go +81 -0
  361. package/linthost/rules_unicorn_no_useless_iterator_to_array.go +72 -0
  362. package/linthost/rules_unicorn_no_useless_length_check.go +144 -0
  363. package/linthost/rules_unicorn_no_useless_promise_resolve_reject.go +81 -0
  364. package/linthost/rules_unicorn_no_useless_spread.go +67 -0
  365. package/linthost/rules_unicorn_no_useless_switch_case.go +55 -0
  366. package/linthost/rules_unicorn_no_useless_undefined.go +55 -0
  367. package/linthost/rules_unicorn_no_zero_fractions.go +52 -0
  368. package/linthost/rules_unicorn_number_literal_case.go +69 -0
  369. package/linthost/rules_unicorn_numeric_separators_style.go +75 -0
  370. package/linthost/rules_unicorn_prefer_add_event_listener.go +66 -0
  371. package/linthost/rules_unicorn_prefer_array_find.go +51 -0
  372. package/linthost/rules_unicorn_prefer_array_flat.go +52 -0
  373. package/linthost/rules_unicorn_prefer_array_flat_map.go +63 -0
  374. package/linthost/rules_unicorn_prefer_array_index_of.go +147 -0
  375. package/linthost/rules_unicorn_prefer_array_some.go +67 -0
  376. package/linthost/rules_unicorn_prefer_at.go +77 -0
  377. package/linthost/rules_unicorn_prefer_bigint_literals.go +77 -0
  378. package/linthost/rules_unicorn_prefer_blob_reading_methods.go +44 -0
  379. package/linthost/rules_unicorn_prefer_class_fields.go +93 -0
  380. package/linthost/rules_unicorn_prefer_classlist_toggle.go +120 -0
  381. package/linthost/rules_unicorn_prefer_code_point.go +49 -0
  382. package/linthost/rules_unicorn_prefer_date_now.go +78 -0
  383. package/linthost/rules_unicorn_prefer_default_parameters.go +144 -0
  384. package/linthost/rules_unicorn_prefer_dom_node_append.go +40 -0
  385. package/linthost/rules_unicorn_prefer_dom_node_dataset.go +55 -0
  386. package/linthost/rules_unicorn_prefer_dom_node_remove.go +41 -0
  387. package/linthost/rules_unicorn_prefer_dom_node_text_content.go +37 -0
  388. package/linthost/rules_unicorn_prefer_event_target.go +36 -0
  389. package/linthost/rules_unicorn_prefer_export_from.go +129 -0
  390. package/linthost/rules_unicorn_prefer_global_this.go +127 -0
  391. package/linthost/rules_unicorn_prefer_import_meta_properties.go +66 -0
  392. package/linthost/rules_unicorn_prefer_includes.go +149 -0
  393. package/linthost/rules_unicorn_prefer_json_parse_buffer.go +65 -0
  394. package/linthost/rules_unicorn_prefer_keyboard_event_key.go +38 -0
  395. package/linthost/rules_unicorn_prefer_logical_operator_over_ternary.go +48 -0
  396. package/linthost/rules_unicorn_prefer_math_min_max.go +60 -0
  397. package/linthost/rules_unicorn_prefer_math_trunc.go +62 -0
  398. package/linthost/rules_unicorn_prefer_modern_dom_apis.go +47 -0
  399. package/linthost/rules_unicorn_prefer_modern_math_apis.go +70 -0
  400. package/linthost/rules_unicorn_prefer_module.go +50 -0
  401. package/linthost/rules_unicorn_prefer_native_coercion_functions.go +114 -0
  402. package/linthost/rules_unicorn_prefer_negative_index.go +74 -0
  403. package/linthost/rules_unicorn_prefer_node_protocol.go +122 -0
  404. package/linthost/rules_unicorn_prefer_number_properties.go +88 -0
  405. package/linthost/rules_unicorn_prefer_object_from_entries.go +55 -0
  406. package/linthost/rules_unicorn_prefer_optional_catch_binding.go +62 -0
  407. package/linthost/rules_unicorn_prefer_prototype_methods.go +54 -0
  408. package/linthost/rules_unicorn_prefer_query_selector.go +56 -0
  409. package/linthost/rules_unicorn_prefer_reflect_apply.go +36 -0
  410. package/linthost/rules_unicorn_prefer_regexp_test_rule.go +80 -0
  411. package/linthost/rules_unicorn_prefer_response_static_json.go +53 -0
  412. package/linthost/rules_unicorn_prefer_set_has.go +42 -0
  413. package/linthost/rules_unicorn_prefer_set_size.go +48 -0
  414. package/linthost/rules_unicorn_prefer_simple_condition_first.go +34 -0
  415. package/linthost/rules_unicorn_prefer_single_call.go +96 -0
  416. package/linthost/rules_unicorn_prefer_spread.go +51 -0
  417. package/linthost/rules_unicorn_prefer_string_raw.go +43 -0
  418. package/linthost/rules_unicorn_prefer_string_replace_all.go +95 -0
  419. package/linthost/rules_unicorn_prefer_string_slice.go +43 -0
  420. package/linthost/rules_unicorn_prefer_string_starts_ends_with.go +148 -0
  421. package/linthost/rules_unicorn_prefer_string_trim_start_end.go +48 -0
  422. package/linthost/rules_unicorn_prefer_structured_clone.go +71 -0
  423. package/linthost/rules_unicorn_prefer_switch.go +103 -0
  424. package/linthost/rules_unicorn_prefer_ternary.go +71 -0
  425. package/linthost/rules_unicorn_prefer_top_level_await.go +72 -0
  426. package/linthost/rules_unicorn_prefer_type_error.go +127 -0
  427. package/linthost/rules_unicorn_prevent_abbreviations.go +127 -0
  428. package/linthost/rules_unicorn_relative_url_style.go +49 -0
  429. package/linthost/rules_unicorn_require_array_join_separator.go +45 -0
  430. package/linthost/rules_unicorn_require_module_attributes.go +54 -0
  431. package/linthost/rules_unicorn_require_module_specifiers.go +55 -0
  432. package/linthost/rules_unicorn_require_number_to_fixed_digits_argument.go +43 -0
  433. package/linthost/rules_unicorn_require_post_message_target_origin.go +44 -0
  434. package/linthost/rules_unicorn_string_content.go +27 -0
  435. package/linthost/rules_unicorn_switch_case_braces.go +42 -0
  436. package/linthost/rules_unicorn_switch_case_break_position.go +31 -0
  437. package/linthost/rules_unicorn_template_indent.go +28 -0
  438. package/linthost/rules_unicorn_text_encoding_identifier_case.go +72 -0
  439. package/linthost/rules_unicorn_throw_new_error.go +61 -0
  440. package/linthost/rules_var.go +10 -4
  441. package/linthost/rules_vitest.go +568 -0
  442. package/package.json +3 -3
  443. package/plugin/main.go +49 -3
  444. package/rule/astutil/astutil.go +10 -3
  445. package/rule/rule.go +12 -10
  446. package/src/defaultFormat.ts +17 -10
  447. package/src/index.ts +65 -43
  448. package/src/structures/ITtscLintConfig.ts +14 -8
  449. package/src/structures/TtscLintRuleSetting.ts +55 -0
  450. package/src/structures/format/ITtscLintFormat.ts +141 -0
  451. package/src/structures/format/ITtscLintFormatJsDoc.ts +18 -0
  452. package/src/structures/format/ITtscLintFormatSortImports.ts +62 -0
  453. package/src/structures/format/index.ts +3 -0
  454. package/src/structures/index.ts +3 -4
  455. package/src/structures/rules/ITtscLintBoundariesRuleOptions.ts +117 -0
  456. package/src/structures/rules/ITtscLintBoundariesRules.ts +91 -0
  457. package/src/structures/rules/ITtscLintContributorRules.ts +20 -0
  458. package/src/structures/rules/ITtscLintCoreRules.ts +1378 -0
  459. package/src/structures/rules/ITtscLintCypressRuleOptions.ts +18 -0
  460. package/src/structures/rules/ITtscLintCypressRules.ts +141 -0
  461. package/src/structures/rules/ITtscLintFunctionalRuleOptions.ts +200 -0
  462. package/src/structures/rules/ITtscLintFunctionalRules.ts +197 -0
  463. package/src/structures/rules/ITtscLintJestRules.ts +209 -0
  464. package/src/structures/rules/ITtscLintJsdocRules.ts +146 -0
  465. package/src/structures/rules/ITtscLintJsxA11yRules.ts +331 -0
  466. package/src/structures/rules/ITtscLintNextjsRules.ts +201 -0
  467. package/src/structures/rules/ITtscLintPlaywrightRules.ts +343 -0
  468. package/src/structures/rules/ITtscLintPromiseRules.ts +196 -0
  469. package/src/structures/rules/ITtscLintReactPerfRuleOptions.ts +19 -0
  470. package/src/structures/rules/ITtscLintReactPerfRules.ts +53 -0
  471. package/src/structures/rules/ITtscLintReactRuleOptions.ts +41 -0
  472. package/src/structures/rules/ITtscLintReactRules.ts +308 -0
  473. package/src/structures/rules/ITtscLintRegexpRules.ts +204 -0
  474. package/src/structures/rules/ITtscLintRuleOptionsMap.ts +88 -0
  475. package/src/structures/rules/ITtscLintRules.ts +77 -0
  476. package/src/structures/rules/ITtscLintSecurityRules.ts +155 -0
  477. package/src/structures/rules/ITtscLintSolidRules.ts +199 -0
  478. package/src/structures/rules/ITtscLintStorybookRuleOptions.ts +22 -0
  479. package/src/structures/rules/ITtscLintStorybookRules.ts +184 -0
  480. package/src/structures/rules/ITtscLintTanstackQueryRules.ts +96 -0
  481. package/src/structures/rules/ITtscLintTestingLibraryRuleOptions.ts +23 -0
  482. package/src/structures/rules/ITtscLintTestingLibraryRules.ts +325 -0
  483. package/src/structures/rules/ITtscLintTypeScriptRules.ts +1172 -0
  484. package/src/structures/rules/ITtscLintUnicornRules.ts +1143 -0
  485. package/src/structures/rules/ITtscLintVitestRules.ts +146 -0
  486. package/src/structures/rules/index.ts +31 -0
  487. package/lib/structures/ITtscLintFormatConfig.d.ts +0 -153
  488. package/lib/structures/ITtscLintFormatConfig.js.map +0 -1
  489. package/lib/structures/TtscLintRule.d.ts +0 -17
  490. package/lib/structures/TtscLintRule.js.map +0 -1
  491. package/lib/structures/TtscLintRuleMap.d.ts +0 -46
  492. package/lib/structures/TtscLintRuleMap.js.map +0 -1
  493. package/lib/structures/TtscLintRuleOptions.d.ts +0 -137
  494. package/lib/structures/TtscLintRuleOptions.js.map +0 -1
  495. package/src/structures/ITtscLintFormatConfig.ts +0 -168
  496. package/src/structures/TtscLintRule.ts +0 -160
  497. package/src/structures/TtscLintRuleMap.ts +0 -55
  498. package/src/structures/TtscLintRuleOptions.ts +0 -151
@@ -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
+ }
@@ -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
+ }