@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,37 @@
1
+ // unicorn/prefer-dom-node-text-content: `HTMLElement#innerText` triggers
2
+ // layout, ignores hidden subtrees, and varies across engines — its
3
+ // `Node#textContent` counterpart returns the raw concatenated text of
4
+ // every descendant text node and is the supported modern shape.
5
+ //
6
+ // AST-only and identifier-text-driven: visit every
7
+ // `PropertyAccessExpression`, match the property name `innerText`, and
8
+ // fire on the property-access node. The receiver expression is not
9
+ // type-checked; the legacy property name is the signal the rule
10
+ // discourages.
11
+ // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-dom-node-text-content.md
12
+ package linthost
13
+
14
+ import shimast "github.com/microsoft/typescript-go/shim/ast"
15
+
16
+ type unicornPreferDomNodeTextContent struct{}
17
+
18
+ func (unicornPreferDomNodeTextContent) Name() string {
19
+ return "unicorn/prefer-dom-node-text-content"
20
+ }
21
+ func (unicornPreferDomNodeTextContent) Visits() []shimast.Kind {
22
+ return []shimast.Kind{shimast.KindPropertyAccessExpression}
23
+ }
24
+ func (unicornPreferDomNodeTextContent) Check(ctx *Context, node *shimast.Node) {
25
+ access := node.AsPropertyAccessExpression()
26
+ if access == nil {
27
+ return
28
+ }
29
+ if identifierText(access.Name()) != "innerText" {
30
+ return
31
+ }
32
+ ctx.Report(node, "Prefer `Node#textContent` over `HTMLElement#innerText`.")
33
+ }
34
+
35
+ func init() {
36
+ Register(unicornPreferDomNodeTextContent{})
37
+ }
@@ -0,0 +1,36 @@
1
+ // unicorn/prefer-event-target: Node's `EventEmitter` is the legacy
2
+ // event API. The browser and modern Node (`>=15`) both ship the
3
+ // standard `EventTarget` interface, which works in both runtimes
4
+ // without a polyfill. Code that needs to run in both should prefer
5
+ // `EventTarget` so it stays portable.
6
+ //
7
+ // AST-only: visit `NewExpression`. Match when the callee is a bare
8
+ // identifier whose name is `EventEmitter`. The receiver is not
9
+ // type-checked — the rule's signal is the literal `new EventEmitter()`
10
+ // shape; a `new events.EventEmitter()` qualified form would not match,
11
+ // matching upstream's own AST-only behavior.
12
+ // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-event-target.md
13
+ package linthost
14
+
15
+ import shimast "github.com/microsoft/typescript-go/shim/ast"
16
+
17
+ type unicornPreferEventTarget struct{}
18
+
19
+ func (unicornPreferEventTarget) Name() string { return "unicorn/prefer-event-target" }
20
+ func (unicornPreferEventTarget) Visits() []shimast.Kind {
21
+ return []shimast.Kind{shimast.KindNewExpression}
22
+ }
23
+ func (unicornPreferEventTarget) Check(ctx *Context, node *shimast.Node) {
24
+ ne := node.AsNewExpression()
25
+ if ne == nil || ne.Expression == nil {
26
+ return
27
+ }
28
+ if identifierText(ne.Expression) != "EventEmitter" {
29
+ return
30
+ }
31
+ ctx.Report(node, "Prefer `EventTarget` over `EventEmitter` when sharing code between Node and the browser.")
32
+ }
33
+
34
+ func init() {
35
+ Register(unicornPreferEventTarget{})
36
+ }
@@ -0,0 +1,129 @@
1
+ // unicorn/prefer-export-from: when the only purpose of a local import is
2
+ // to re-export it under the same name, the canonical shape is the
3
+ // `export { X } from "Y"` re-export, which skips the intermediate local
4
+ // binding entirely. The split `import { X } from "Y"; export { X };`
5
+ // form is longer, allocates a binding that never gets used, and reads
6
+ // as if the author meant to consume `X` locally before deciding not to.
7
+ //
8
+ // AST-only minimum-viable port: visit `SourceFile` and walk top-level
9
+ // statements once. Build a map from each unrenamed named-binding of an
10
+ // `import { X } from "Y"` declaration to its module specifier text, then
11
+ // fire on every later `export { X };` statement (no rename, no
12
+ // `from`-clause) whose identifier appears in that map. Default and
13
+ // namespace imports, renamed bindings, and re-exports with their own
14
+ // `from`-clause are out of scope; the MVP only catches the textbook
15
+ // "import then immediately re-export" pair.
16
+ // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-export-from.md
17
+ package linthost
18
+
19
+ import shimast "github.com/microsoft/typescript-go/shim/ast"
20
+
21
+ type unicornPreferExportFrom struct{}
22
+
23
+ func (unicornPreferExportFrom) Name() string { return "unicorn/prefer-export-from" }
24
+ func (unicornPreferExportFrom) Visits() []shimast.Kind {
25
+ return []shimast.Kind{shimast.KindSourceFile}
26
+ }
27
+ func (unicornPreferExportFrom) Check(ctx *Context, node *shimast.Node) {
28
+ statements := node.Statements()
29
+ if len(statements) == 0 {
30
+ return
31
+ }
32
+ // Map of locally-imported simple binding name → true. Built on a
33
+ // first pass so a re-export earlier in the file does not accidentally
34
+ // match an import declared later; the upstream rule is anchored on
35
+ // "imported above, re-exported below" ordering.
36
+ imported := map[string]bool{}
37
+ for _, stmt := range statements {
38
+ if stmt == nil || stmt.Kind != shimast.KindImportDeclaration {
39
+ continue
40
+ }
41
+ decl := stmt.AsImportDeclaration()
42
+ if decl == nil || decl.ImportClause == nil {
43
+ continue
44
+ }
45
+ clause := decl.ImportClause.AsImportClause()
46
+ if clause == nil || clause.NamedBindings == nil ||
47
+ clause.NamedBindings.Kind != shimast.KindNamedImports {
48
+ continue
49
+ }
50
+ // A default-bound or namespace-mixed import is out of scope: the
51
+ // MVP only rewrites pure `import { X } from "Y"` pairs.
52
+ if clause.Name() != nil {
53
+ continue
54
+ }
55
+ named := clause.NamedBindings.AsNamedImports()
56
+ if named == nil || named.Elements == nil {
57
+ continue
58
+ }
59
+ for _, spec := range named.Elements.Nodes {
60
+ s := spec.AsImportSpecifier()
61
+ if s == nil {
62
+ continue
63
+ }
64
+ // PropertyName is set only when the specifier is renamed
65
+ // (`import { a as b }`); skip those — `export { b }` would
66
+ // require `export { b as b } from "Y"` which is itself a
67
+ // useless rename.
68
+ if s.PropertyName != nil {
69
+ continue
70
+ }
71
+ name := identifierText(s.Name())
72
+ if name == "" {
73
+ continue
74
+ }
75
+ imported[name] = true
76
+ }
77
+ }
78
+ if len(imported) == 0 {
79
+ return
80
+ }
81
+ for _, stmt := range statements {
82
+ if stmt == nil || stmt.Kind != shimast.KindExportDeclaration {
83
+ continue
84
+ }
85
+ decl := stmt.AsExportDeclaration()
86
+ if decl == nil || decl.ExportClause == nil {
87
+ continue
88
+ }
89
+ // Skip `export { X } from "Y"` — already in the target shape.
90
+ if decl.ModuleSpecifier != nil {
91
+ continue
92
+ }
93
+ if decl.ExportClause.Kind != shimast.KindNamedExports {
94
+ continue
95
+ }
96
+ named := decl.ExportClause.AsNamedExports()
97
+ if named == nil || named.Elements == nil || len(named.Elements.Nodes) == 0 {
98
+ continue
99
+ }
100
+ matched := false
101
+ for _, el := range named.Elements.Nodes {
102
+ spec := el.AsExportSpecifier()
103
+ if spec == nil {
104
+ continue
105
+ }
106
+ // PropertyName != nil means `export { a as b }` — a rename
107
+ // the from-clause rewrite cannot preserve without also
108
+ // touching the import side. Skip.
109
+ if spec.PropertyName != nil {
110
+ continue
111
+ }
112
+ name := identifierText(spec.Name())
113
+ if name == "" {
114
+ continue
115
+ }
116
+ if imported[name] {
117
+ matched = true
118
+ break
119
+ }
120
+ }
121
+ if matched {
122
+ ctx.Report(stmt, "Use `export { X } from \"Y\"` instead of importing then re-exporting.")
123
+ }
124
+ }
125
+ }
126
+
127
+ func init() {
128
+ Register(unicornPreferExportFrom{})
129
+ }
@@ -0,0 +1,127 @@
1
+ // unicorn/prefer-global-this: `window`, `self`, and `global` are
2
+ // environment-specific global aliases. Using them locks code to a
3
+ // single runtime (browser, worker, Node) and forces feature-detection
4
+ // boilerplate when the same code needs to run elsewhere. `globalThis`
5
+ // is the standardized cross-runtime alias and the canonical form for
6
+ // the same reference.
7
+ //
8
+ // AST-only: visit every `Identifier`. The rule fires only when the
9
+ // identifier sits in a value-expression position; declaration names,
10
+ // property-access right sides, parameter names, property-assignment
11
+ // keys, and type references are filtered out by parent-kind gating so
12
+ // the diagnostic is anchored on actual reads of the global.
13
+ // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-global-this.md
14
+ package linthost
15
+
16
+ import shimast "github.com/microsoft/typescript-go/shim/ast"
17
+
18
+ type unicornPreferGlobalThis struct{}
19
+
20
+ func (unicornPreferGlobalThis) Name() string { return "unicorn/prefer-global-this" }
21
+ func (unicornPreferGlobalThis) Visits() []shimast.Kind {
22
+ return []shimast.Kind{shimast.KindIdentifier}
23
+ }
24
+ func (unicornPreferGlobalThis) Check(ctx *Context, node *shimast.Node) {
25
+ name := identifierText(node)
26
+ switch name {
27
+ case "window", "self", "global":
28
+ default:
29
+ return
30
+ }
31
+ if !isUnicornValuePositionIdentifier(node) {
32
+ return
33
+ }
34
+ ctx.Report(node, "Prefer `globalThis` over `window` / `self` / `global`.")
35
+ }
36
+
37
+ // isUnicornValuePositionIdentifier reports whether `node` (a bare
38
+ // Identifier) appears in a value-expression position rather than as a
39
+ // binding name, property key, member-access right side, or type
40
+ // reference. Declaration names and property keys are read positions
41
+ // for the *name* itself, so they must not contribute to rules that
42
+ // flag *uses* of a global.
43
+ func isUnicornValuePositionIdentifier(node *shimast.Node) bool {
44
+ if node == nil || node.Kind != shimast.KindIdentifier || node.Parent == nil {
45
+ return false
46
+ }
47
+ parent := node.Parent
48
+ switch parent.Kind {
49
+ case shimast.KindVariableDeclaration:
50
+ decl := parent.AsVariableDeclaration()
51
+ if decl != nil && decl.Name() == node {
52
+ return false
53
+ }
54
+ case shimast.KindBindingElement:
55
+ elem := parent.AsBindingElement()
56
+ if elem != nil && elem.Name() == node {
57
+ return false
58
+ }
59
+ case shimast.KindParameter:
60
+ param := parent.AsParameterDeclaration()
61
+ if param != nil && param.Name() == node {
62
+ return false
63
+ }
64
+ case shimast.KindFunctionDeclaration:
65
+ fn := parent.AsFunctionDeclaration()
66
+ if fn != nil && fn.Name() == node {
67
+ return false
68
+ }
69
+ case shimast.KindFunctionExpression:
70
+ fn := parent.AsFunctionExpression()
71
+ if fn != nil && fn.Name() == node {
72
+ return false
73
+ }
74
+ case shimast.KindClassDeclaration:
75
+ cls := parent.AsClassDeclaration()
76
+ if cls != nil && cls.Name() == node {
77
+ return false
78
+ }
79
+ case shimast.KindClassExpression:
80
+ cls := parent.AsClassExpression()
81
+ if cls != nil && cls.Name() == node {
82
+ return false
83
+ }
84
+ case shimast.KindPropertyAccessExpression:
85
+ access := parent.AsPropertyAccessExpression()
86
+ if access != nil && access.Name() == node {
87
+ return false
88
+ }
89
+ case shimast.KindPropertyAssignment:
90
+ prop := parent.AsPropertyAssignment()
91
+ if prop != nil && prop.Name() == node {
92
+ return false
93
+ }
94
+ case shimast.KindShorthandPropertyAssignment:
95
+ // `{window}` shorthand — the identifier is both name and read,
96
+ // but the read here is the value position, so allow.
97
+ case shimast.KindMethodDeclaration,
98
+ shimast.KindGetAccessor,
99
+ shimast.KindSetAccessor,
100
+ shimast.KindPropertyDeclaration:
101
+ // These have a Name() slot that is not a value expression.
102
+ return false
103
+ case shimast.KindTypeReference,
104
+ shimast.KindQualifiedName,
105
+ shimast.KindImportSpecifier,
106
+ shimast.KindExportSpecifier,
107
+ shimast.KindNamespaceImport,
108
+ shimast.KindImportClause,
109
+ shimast.KindNamespaceExport,
110
+ shimast.KindLabeledStatement,
111
+ shimast.KindBreakStatement,
112
+ shimast.KindContinueStatement,
113
+ shimast.KindJsxAttribute,
114
+ shimast.KindEnumDeclaration,
115
+ shimast.KindEnumMember,
116
+ shimast.KindModuleDeclaration,
117
+ shimast.KindTypeParameter,
118
+ shimast.KindInterfaceDeclaration,
119
+ shimast.KindTypeAliasDeclaration:
120
+ return false
121
+ }
122
+ return true
123
+ }
124
+
125
+ func init() {
126
+ Register(unicornPreferGlobalThis{})
127
+ }
@@ -0,0 +1,66 @@
1
+ // unicorn/prefer-import-meta-properties: the legacy
2
+ // `fileURLToPath(import.meta.url)` pattern was the only way to obtain
3
+ // the on-disk path of the current ES module before Node added the
4
+ // dedicated `import.meta.dirname` and `import.meta.filename`
5
+ // properties. Once those exist, the workaround is pure noise — it
6
+ // imports `url` for one call and adds a layer the reader has to
7
+ // translate back to "the current file's directory / filename".
8
+ //
9
+ // AST-only: visit `CallExpression`, match a bare `fileURLToPath`
10
+ // callee, and check that the sole argument is the property access
11
+ // `import.meta.url`. The canonical legacy shape is the only case
12
+ // covered — other call sites of `fileURLToPath` are out of scope.
13
+ // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-import-meta-properties.md
14
+ package linthost
15
+
16
+ import shimast "github.com/microsoft/typescript-go/shim/ast"
17
+
18
+ type unicornPreferImportMetaProperties struct{}
19
+
20
+ func (unicornPreferImportMetaProperties) Name() string {
21
+ return "unicorn/prefer-import-meta-properties"
22
+ }
23
+ func (unicornPreferImportMetaProperties) Visits() []shimast.Kind {
24
+ return []shimast.Kind{shimast.KindCallExpression}
25
+ }
26
+ func (unicornPreferImportMetaProperties) Check(ctx *Context, node *shimast.Node) {
27
+ call := node.AsCallExpression()
28
+ if call == nil || call.Expression == nil {
29
+ return
30
+ }
31
+ if identifierText(call.Expression) != "fileURLToPath" {
32
+ return
33
+ }
34
+ if call.Arguments == nil || len(call.Arguments.Nodes) != 1 {
35
+ return
36
+ }
37
+ arg := stripParens(call.Arguments.Nodes[0])
38
+ if arg == nil || arg.Kind != shimast.KindPropertyAccessExpression {
39
+ return
40
+ }
41
+ access := arg.AsPropertyAccessExpression()
42
+ if access == nil {
43
+ return
44
+ }
45
+ if identifierText(access.Name()) != "url" {
46
+ return
47
+ }
48
+ receiver := stripParens(access.Expression)
49
+ if receiver == nil {
50
+ return
51
+ }
52
+ // `import.meta` parses as either a MetaProperty token or a
53
+ // PropertyAccess(import, meta) chain depending on the path; both
54
+ // resolve textually to the same source span.
55
+ if receiver.Kind == shimast.KindMetaProperty {
56
+ ctx.Report(node, "Prefer `import.meta.dirname` / `import.meta.filename` over `fileURLToPath(import.meta.url)`.")
57
+ return
58
+ }
59
+ if isMatchingPropertyAccess(receiver, "import", "meta") {
60
+ ctx.Report(node, "Prefer `import.meta.dirname` / `import.meta.filename` over `fileURLToPath(import.meta.url)`.")
61
+ }
62
+ }
63
+
64
+ func init() {
65
+ Register(unicornPreferImportMetaProperties{})
66
+ }
@@ -0,0 +1,149 @@
1
+ // unicorn/prefer-includes: `arr.indexOf(x) !== -1` (and its `=== -1`,
2
+ // `> -1`, `>= 0`, `< 0` siblings) is the legacy idiom for membership
3
+ // testing. The intent is obvious only after the reader translates the
4
+ // magic number; `arr.includes(x)` says the same thing without the
5
+ // translation step. The rule applies to both arrays and strings — both
6
+ // expose `indexOf` and both expose `includes`.
7
+ //
8
+ // AST-only: a `BinaryExpression` whose operator is one of the
9
+ // recognized comparisons and whose operands are `<call>.indexOf(...)`
10
+ // vs. one of `-1` / `0` (allowing the literal-or-unary-minus shape for
11
+ // `-1`) matches. For symmetric operators (`===`, `!==`, `==`, `!=`)
12
+ // either operand may carry the call. For asymmetric operators (`<`,
13
+ // `>=`, `>`) only the canonical orientation `indexOf(x) <op> <literal>`
14
+ // is recognized; the swapped form (`0 < indexOf(x)`) has different
15
+ // semantics (e.g. "found at index >= 1") and is intentionally NOT
16
+ // rewritten to `includes`.
17
+ // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-includes.md
18
+ package linthost
19
+
20
+ import shimast "github.com/microsoft/typescript-go/shim/ast"
21
+
22
+ type unicornPreferIncludes struct{}
23
+
24
+ func (unicornPreferIncludes) Name() string { return "unicorn/prefer-includes" }
25
+ func (unicornPreferIncludes) Visits() []shimast.Kind {
26
+ return []shimast.Kind{shimast.KindBinaryExpression}
27
+ }
28
+ func (unicornPreferIncludes) Check(ctx *Context, node *shimast.Node) {
29
+ bin := node.AsBinaryExpression()
30
+ if bin == nil || bin.OperatorToken == nil || bin.Left == nil || bin.Right == nil {
31
+ return
32
+ }
33
+ op := bin.OperatorToken.Kind
34
+ wantNegOne := false
35
+ wantZero := false
36
+ switch op {
37
+ case shimast.KindEqualsEqualsEqualsToken,
38
+ shimast.KindExclamationEqualsEqualsToken,
39
+ shimast.KindEqualsEqualsToken,
40
+ shimast.KindExclamationEqualsToken:
41
+ wantNegOne = true
42
+ case shimast.KindLessThanToken:
43
+ // `indexOf(x) < 0`
44
+ wantZero = true
45
+ case shimast.KindGreaterThanEqualsToken:
46
+ // `indexOf(x) >= 0`
47
+ wantZero = true
48
+ case shimast.KindGreaterThanToken:
49
+ // Not in the canonical set for this orientation; handled below
50
+ // via `> -1` matching against the negative-one form.
51
+ wantNegOne = true
52
+ default:
53
+ return
54
+ }
55
+ left := stripParens(bin.Left)
56
+ right := stripParens(bin.Right)
57
+ matched := unicornPreferIncludesMatches(left, right, op, wantNegOne, wantZero)
58
+ // Equality is symmetric — also try the swapped orientation.
59
+ // Asymmetric operators (`<`, `>=`, `>`) only match the canonical
60
+ // orientation; swapping `indexOf(x) < 0` to `0 < indexOf(x)` changes
61
+ // the meaning ("found at index >= 1") and must not be rewritten.
62
+ if !matched {
63
+ switch op {
64
+ case shimast.KindEqualsEqualsEqualsToken,
65
+ shimast.KindExclamationEqualsEqualsToken,
66
+ shimast.KindEqualsEqualsToken,
67
+ shimast.KindExclamationEqualsToken:
68
+ matched = unicornPreferIncludesMatches(right, left, op, wantNegOne, wantZero)
69
+ }
70
+ }
71
+ if matched {
72
+ ctx.Report(node, "Prefer `Array#includes()` / `String#includes()` over `indexOf` comparisons.")
73
+ }
74
+ }
75
+
76
+ func unicornPreferIncludesMatches(
77
+ callSide, literalSide *shimast.Node,
78
+ op shimast.Kind,
79
+ wantNegOne, wantZero bool,
80
+ ) bool {
81
+ if callSide == nil || literalSide == nil {
82
+ return false
83
+ }
84
+ if callSide.Kind != shimast.KindCallExpression {
85
+ return false
86
+ }
87
+ call := callSide.AsCallExpression()
88
+ if call == nil || call.Expression == nil ||
89
+ call.Expression.Kind != shimast.KindPropertyAccessExpression {
90
+ return false
91
+ }
92
+ access := call.Expression.AsPropertyAccessExpression()
93
+ if access == nil || identifierText(access.Name()) != "indexOf" {
94
+ return false
95
+ }
96
+ // `> -1`, `>= 0`, `< 0`, `=== -1`, `!== -1`, `== -1`, `!= -1`.
97
+ switch op {
98
+ case shimast.KindGreaterThanToken:
99
+ // Only `indexOf(x) > -1` matches.
100
+ return unicornPreferIncludesIsNegativeOne(literalSide)
101
+ case shimast.KindLessThanToken:
102
+ // Only `indexOf(x) < 0` matches.
103
+ return unicornPreferIncludesIsZero(literalSide)
104
+ case shimast.KindGreaterThanEqualsToken:
105
+ // Only `indexOf(x) >= 0` matches.
106
+ return unicornPreferIncludesIsZero(literalSide)
107
+ }
108
+ if wantNegOne && unicornPreferIncludesIsNegativeOne(literalSide) {
109
+ return true
110
+ }
111
+ if wantZero && unicornPreferIncludesIsZero(literalSide) {
112
+ return true
113
+ }
114
+ return false
115
+ }
116
+
117
+ func unicornPreferIncludesIsNegativeOne(node *shimast.Node) bool {
118
+ node = stripParens(node)
119
+ if node == nil {
120
+ return false
121
+ }
122
+ if node.Kind == shimast.KindPrefixUnaryExpression {
123
+ prefix := node.AsPrefixUnaryExpression()
124
+ if prefix == nil || prefix.Operator != shimast.KindMinusToken || prefix.Operand == nil {
125
+ return false
126
+ }
127
+ if prefix.Operand.Kind != shimast.KindNumericLiteral {
128
+ return false
129
+ }
130
+ return numericLiteralText(prefix.Operand) == "1"
131
+ }
132
+ if node.Kind == shimast.KindNumericLiteral {
133
+ // Some tokenizers preserve the leading `-` in the literal text.
134
+ return numericLiteralText(node) == "-1"
135
+ }
136
+ return false
137
+ }
138
+
139
+ func unicornPreferIncludesIsZero(node *shimast.Node) bool {
140
+ node = stripParens(node)
141
+ if node == nil || node.Kind != shimast.KindNumericLiteral {
142
+ return false
143
+ }
144
+ return numericLiteralText(node) == "0"
145
+ }
146
+
147
+ func init() {
148
+ Register(unicornPreferIncludes{})
149
+ }
@@ -0,0 +1,65 @@
1
+ // unicorn/prefer-json-parse-buffer: as of Node 21, `JSON.parse`
2
+ // accepts a `Buffer` directly and decodes it internally, so the common
3
+ // `JSON.parse(buf.toString())` pattern allocates an extra intermediate
4
+ // string for nothing. Dropping the `.toString()` avoids the allocation
5
+ // and reads at least as clearly.
6
+ //
7
+ // AST-only: visit `CallExpression`. Match the outer call where the
8
+ // callee is `JSON.parse` (`PropertyAccess(Identifier("JSON"), parse)`)
9
+ // AND the single argument is itself a `CallExpression` whose callee is
10
+ // `PropertyAccess(_, toString)` taking no arguments — i.e. the
11
+ // syntactic shape `JSON.parse(x.toString())`. The receiver type of
12
+ // `x` is not checked, so non-buffer receivers will produce false
13
+ // positives; this is the documented trade for an AST-only port.
14
+ // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-json-parse-buffer.md
15
+ package linthost
16
+
17
+ import shimast "github.com/microsoft/typescript-go/shim/ast"
18
+
19
+ type unicornPreferJsonParseBuffer struct{}
20
+
21
+ func (unicornPreferJsonParseBuffer) Name() string { return "unicorn/prefer-json-parse-buffer" }
22
+ func (unicornPreferJsonParseBuffer) Visits() []shimast.Kind {
23
+ return []shimast.Kind{shimast.KindCallExpression}
24
+ }
25
+ func (unicornPreferJsonParseBuffer) Check(ctx *Context, node *shimast.Node) {
26
+ call := node.AsCallExpression()
27
+ if call == nil || call.Expression == nil || call.Arguments == nil || len(call.Arguments.Nodes) != 1 {
28
+ return
29
+ }
30
+ // Callee must be `JSON.parse`.
31
+ if call.Expression.Kind != shimast.KindPropertyAccessExpression {
32
+ return
33
+ }
34
+ access := call.Expression.AsPropertyAccessExpression()
35
+ if access == nil {
36
+ return
37
+ }
38
+ if identifierText(access.Expression) != "JSON" || identifierText(access.Name()) != "parse" {
39
+ return
40
+ }
41
+ // Argument must be `_.toString()` with no arguments.
42
+ arg := stripParens(call.Arguments.Nodes[0])
43
+ if arg == nil || arg.Kind != shimast.KindCallExpression {
44
+ return
45
+ }
46
+ innerCall := arg.AsCallExpression()
47
+ if innerCall == nil || innerCall.Expression == nil {
48
+ return
49
+ }
50
+ if innerCall.Arguments != nil && len(innerCall.Arguments.Nodes) != 0 {
51
+ return
52
+ }
53
+ if innerCall.Expression.Kind != shimast.KindPropertyAccessExpression {
54
+ return
55
+ }
56
+ innerAccess := innerCall.Expression.AsPropertyAccessExpression()
57
+ if innerAccess == nil || identifierText(innerAccess.Name()) != "toString" {
58
+ return
59
+ }
60
+ ctx.Report(node, "Prefer passing a `Buffer` directly to `JSON.parse` (Node 21+) over decoding to a string first.")
61
+ }
62
+
63
+ func init() {
64
+ Register(unicornPreferJsonParseBuffer{})
65
+ }
@@ -0,0 +1,38 @@
1
+ // unicorn/prefer-keyboard-event-key: `KeyboardEvent#keyCode`,
2
+ // `KeyboardEvent#charCode`, and `KeyboardEvent#which` are all
3
+ // deprecated. They expose layout-dependent integer codes that change
4
+ // across browsers and keyboard layouts and force code to maintain
5
+ // magic-number tables. `KeyboardEvent#key` returns the resolved key
6
+ // label as a string and is the spec-blessed replacement.
7
+ //
8
+ // AST-only: visit `PropertyAccessExpression` and match the right-hand
9
+ // identifier name against the deprecated property set. The receiver
10
+ // is intentionally not type-checked — the rule accepts the syntactic
11
+ // shape as the signal, which produces a small number of harmless
12
+ // false positives on non-event objects but is the correct trade for
13
+ // an AST-only port.
14
+ // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-keyboard-event-key.md
15
+ package linthost
16
+
17
+ import shimast "github.com/microsoft/typescript-go/shim/ast"
18
+
19
+ type unicornPreferKeyboardEventKey struct{}
20
+
21
+ func (unicornPreferKeyboardEventKey) Name() string { return "unicorn/prefer-keyboard-event-key" }
22
+ func (unicornPreferKeyboardEventKey) Visits() []shimast.Kind {
23
+ return []shimast.Kind{shimast.KindPropertyAccessExpression}
24
+ }
25
+ func (unicornPreferKeyboardEventKey) Check(ctx *Context, node *shimast.Node) {
26
+ access := node.AsPropertyAccessExpression()
27
+ if access == nil {
28
+ return
29
+ }
30
+ switch identifierText(access.Name()) {
31
+ case "keyCode", "charCode", "which":
32
+ ctx.Report(node, "Prefer `KeyboardEvent#key` over the deprecated `keyCode` / `charCode` / `which`.")
33
+ }
34
+ }
35
+
36
+ func init() {
37
+ Register(unicornPreferKeyboardEventKey{})
38
+ }