@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,532 @@
1
+ package linthost
2
+
3
+ import (
4
+ "encoding/json"
5
+ "fmt"
6
+ "os"
7
+ "path/filepath"
8
+ "regexp"
9
+ "sort"
10
+ "strings"
11
+
12
+ shimast "github.com/microsoft/typescript-go/shim/ast"
13
+ )
14
+
15
+ type boundariesElementTypes struct{}
16
+ type boundariesExternal struct{}
17
+ type boundariesEntryPoint struct{}
18
+ type boundariesNoPrivate struct{}
19
+ type boundariesNoUnknown struct{}
20
+
21
+ // boundariesDependencies is a v1 stub for the upstream unified
22
+ // `boundaries/dependencies` rule, which replaces the legacy
23
+ // `element-types` / `entry-point` / `external` / `no-private` /
24
+ // `no-unknown` rules with a single direction-aware policy block.
25
+ //
26
+ // The native engine accepts the same `elements` + `rules` config shape so
27
+ // projects can claim the rule id today, but the full direction
28
+ // validation is deferred. Until then this rule registers, decodes
29
+ // options without crashing, and emits no diagnostics.
30
+ type boundariesDependencies struct{}
31
+
32
+ func (boundariesElementTypes) Name() string { return "boundaries/element-types" }
33
+ func (boundariesExternal) Name() string { return "boundaries/external" }
34
+ func (boundariesEntryPoint) Name() string { return "boundaries/entry-point" }
35
+ func (boundariesNoPrivate) Name() string { return "boundaries/no-private" }
36
+ func (boundariesNoUnknown) Name() string { return "boundaries/no-unknown" }
37
+ func (boundariesDependencies) Name() string { return "boundaries/dependencies" }
38
+
39
+ func (boundariesElementTypes) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindSourceFile} }
40
+ func (boundariesExternal) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindSourceFile} }
41
+ func (boundariesEntryPoint) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindSourceFile} }
42
+ func (boundariesNoPrivate) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindSourceFile} }
43
+ func (boundariesNoUnknown) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindSourceFile} }
44
+ func (boundariesDependencies) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindSourceFile} }
45
+
46
+ // Check is intentionally a no-op for the v1 stub. The rule accepts the
47
+ // upstream config shape via the shared `boundariesOptions` decoder so
48
+ // downstream configs type-check and load, then exits without reporting
49
+ // findings. Replace this body when the unified direction validation
50
+ // lands.
51
+ func (boundariesDependencies) Check(ctx *Context, node *shimast.Node) {
52
+ _ = decodeBoundariesOptions(ctx)
53
+ }
54
+
55
+ func (boundariesElementTypes) Check(ctx *Context, node *shimast.Node) {
56
+ opts := decodeBoundariesOptions(ctx)
57
+ if len(opts.Elements) == 0 {
58
+ return
59
+ }
60
+ source := classifyBoundaryFile(ctx.File.FileName(), opts.Elements)
61
+ if source == nil {
62
+ return
63
+ }
64
+ for _, dep := range collectBoundaryDependencies(node) {
65
+ if !dep.relative {
66
+ continue
67
+ }
68
+ targetPath, ok := resolveBoundaryImport(ctx.File.FileName(), dep.specifier)
69
+ if !ok {
70
+ continue
71
+ }
72
+ target := classifyBoundaryFile(targetPath, opts.Elements)
73
+ if target == nil {
74
+ continue
75
+ }
76
+ policy, rule := evaluateBoundaryPolicy(opts, source.Type, target.Type)
77
+ if policy != "disallow" {
78
+ continue
79
+ }
80
+ message := fmt.Sprintf("Import from boundary element %q is not allowed in %q.", target.Type, source.Type)
81
+ if rule != nil && rule.Message != "" {
82
+ message = rule.Message
83
+ }
84
+ reportBoundaryDependency(ctx, dep, message)
85
+ }
86
+ }
87
+
88
+ func (boundariesExternal) Check(ctx *Context, node *shimast.Node) {
89
+ opts := decodeBoundariesOptions(ctx)
90
+ for _, dep := range collectBoundaryDependencies(node) {
91
+ if dep.relative {
92
+ continue
93
+ }
94
+ name := boundaryPackageName(dep.specifier)
95
+ disallowed := matchAnyBoundaryPattern(opts.Disallow, dep.specifier, name)
96
+ allowed := len(opts.Allow) == 0 || matchAnyBoundaryPattern(opts.Allow, dep.specifier, name)
97
+ if !disallowed && allowed {
98
+ continue
99
+ }
100
+ message := fmt.Sprintf("External dependency %q is not allowed.", dep.specifier)
101
+ if opts.Message != "" {
102
+ message = opts.Message
103
+ }
104
+ reportBoundaryDependency(ctx, dep, message)
105
+ }
106
+ }
107
+
108
+ func (boundariesEntryPoint) Check(ctx *Context, node *shimast.Node) {
109
+ opts := decodeBoundariesOptions(ctx)
110
+ if len(opts.Elements) == 0 {
111
+ return
112
+ }
113
+ source := classifyBoundaryFile(ctx.File.FileName(), opts.Elements)
114
+ for _, dep := range collectBoundaryDependencies(node) {
115
+ if !dep.relative {
116
+ continue
117
+ }
118
+ targetPath, ok := resolveBoundaryImport(ctx.File.FileName(), dep.specifier)
119
+ if !ok {
120
+ continue
121
+ }
122
+ target := classifyBoundaryFile(targetPath, opts.Elements)
123
+ if target == nil || len(target.Entry) == 0 {
124
+ continue
125
+ }
126
+ if source != nil && source.RootPath == target.RootPath {
127
+ continue
128
+ }
129
+ if matchBoundaryElementLocalPattern(target.Entry, target) {
130
+ continue
131
+ }
132
+ reportBoundaryDependency(ctx, dep, fmt.Sprintf("Import %q through an allowed boundary entry point.", target.RelativePath))
133
+ }
134
+ }
135
+
136
+ func (boundariesNoPrivate) Check(ctx *Context, node *shimast.Node) {
137
+ opts := decodeBoundariesOptions(ctx)
138
+ if len(opts.Elements) == 0 {
139
+ return
140
+ }
141
+ source := classifyBoundaryFile(ctx.File.FileName(), opts.Elements)
142
+ if source == nil {
143
+ return
144
+ }
145
+ for _, dep := range collectBoundaryDependencies(node) {
146
+ if !dep.relative {
147
+ continue
148
+ }
149
+ targetPath, ok := resolveBoundaryImport(ctx.File.FileName(), dep.specifier)
150
+ if !ok {
151
+ continue
152
+ }
153
+ target := classifyBoundaryFile(targetPath, opts.Elements)
154
+ if target == nil || len(target.Private) == 0 {
155
+ continue
156
+ }
157
+ if source.RootPath == target.RootPath || !matchBoundaryElementLocalPattern(target.Private, target) {
158
+ continue
159
+ }
160
+ reportBoundaryDependency(ctx, dep, fmt.Sprintf("Do not import private boundary file %q from another element.", target.RelativePath))
161
+ }
162
+ }
163
+
164
+ func (boundariesNoUnknown) Check(ctx *Context, node *shimast.Node) {
165
+ opts := decodeBoundariesOptions(ctx)
166
+ if len(opts.Elements) == 0 {
167
+ return
168
+ }
169
+ for _, dep := range collectBoundaryDependencies(node) {
170
+ if !dep.relative {
171
+ continue
172
+ }
173
+ targetPath, ok := resolveBoundaryImport(ctx.File.FileName(), dep.specifier)
174
+ if !ok {
175
+ continue
176
+ }
177
+ if classifyBoundaryFile(targetPath, opts.Elements) != nil {
178
+ continue
179
+ }
180
+ reportBoundaryDependency(ctx, dep, fmt.Sprintf("Imported file %q does not match any configured boundary element.", boundaryDisplayPath(targetPath)))
181
+ }
182
+ }
183
+
184
+ type boundaryStringList []string
185
+
186
+ func (l *boundaryStringList) UnmarshalJSON(data []byte) error {
187
+ if string(data) == "null" {
188
+ *l = nil
189
+ return nil
190
+ }
191
+ var single string
192
+ if err := json.Unmarshal(data, &single); err == nil {
193
+ *l = boundaryStringList{single}
194
+ return nil
195
+ }
196
+ var many []string
197
+ if err := json.Unmarshal(data, &many); err != nil {
198
+ return err
199
+ }
200
+ *l = boundaryStringList(many)
201
+ return nil
202
+ }
203
+
204
+ type boundariesOptions struct {
205
+ Elements []boundaryElement `json:"elements"`
206
+ Rules []boundaryPolicyRule `json:"rules"`
207
+ Default string `json:"default"`
208
+ Allow boundaryStringList `json:"allow"`
209
+ Disallow boundaryStringList `json:"disallow"`
210
+ Message string `json:"message"`
211
+ }
212
+
213
+ type boundaryElement struct {
214
+ Type string `json:"type"`
215
+ Pattern string `json:"pattern"`
216
+ Entry boundaryStringList `json:"entry"`
217
+ Private boundaryStringList `json:"private"`
218
+ }
219
+
220
+ type boundaryPolicyRule struct {
221
+ From boundaryStringList `json:"from"`
222
+ Allow boundaryStringList `json:"allow"`
223
+ Disallow boundaryStringList `json:"disallow"`
224
+ Message string `json:"message"`
225
+ }
226
+
227
+ type boundaryFile struct {
228
+ Element boundaryElement
229
+ Type string
230
+ Path string
231
+ RelativePath string
232
+ RootPath string
233
+ LocalPath string
234
+ Entry boundaryStringList
235
+ Private boundaryStringList
236
+ }
237
+
238
+ type boundaryDependency struct {
239
+ node *shimast.Node
240
+ specifier string
241
+ relative bool
242
+ }
243
+
244
+ func decodeBoundariesOptions(ctx *Context) boundariesOptions {
245
+ var opts boundariesOptions
246
+ if ctx != nil {
247
+ _ = ctx.DecodeOptions(&opts)
248
+ }
249
+ return opts
250
+ }
251
+
252
+ func collectBoundaryDependencies(node *shimast.Node) []boundaryDependency {
253
+ out := []boundaryDependency{}
254
+ var walk func(*shimast.Node)
255
+ walk = func(n *shimast.Node) {
256
+ if n == nil {
257
+ return
258
+ }
259
+ switch n.Kind {
260
+ case shimast.KindImportDeclaration:
261
+ if imp := n.AsImportDeclaration(); imp != nil && imp.ModuleSpecifier != nil {
262
+ specifier := stringLiteralText(imp.ModuleSpecifier)
263
+ if specifier != "" {
264
+ out = append(out, boundaryDependency{
265
+ node: imp.ModuleSpecifier,
266
+ specifier: specifier,
267
+ relative: isRelativeBoundarySpecifier(specifier),
268
+ })
269
+ }
270
+ }
271
+ case shimast.KindExportDeclaration:
272
+ if exp := n.AsExportDeclaration(); exp != nil && exp.ModuleSpecifier != nil {
273
+ specifier := stringLiteralText(exp.ModuleSpecifier)
274
+ if specifier != "" {
275
+ out = append(out, boundaryDependency{
276
+ node: exp.ModuleSpecifier,
277
+ specifier: specifier,
278
+ relative: isRelativeBoundarySpecifier(specifier),
279
+ })
280
+ }
281
+ }
282
+ }
283
+ n.ForEachChild(func(child *shimast.Node) bool {
284
+ walk(child)
285
+ return false
286
+ })
287
+ }
288
+ walk(node)
289
+ return out
290
+ }
291
+
292
+ func classifyBoundaryFile(fileName string, elements []boundaryElement) *boundaryFile {
293
+ normalized := normalizeBoundaryPath(fileName)
294
+ matches := []boundaryFile{}
295
+ for _, elem := range elements {
296
+ if elem.Type == "" || elem.Pattern == "" {
297
+ continue
298
+ }
299
+ rel, ok := boundaryRelativeMatch(elem.Pattern, normalized)
300
+ if !ok {
301
+ continue
302
+ }
303
+ root := boundaryElementRoot(elem.Pattern, rel)
304
+ local := rel
305
+ if root != "" {
306
+ local = strings.TrimPrefix(rel, root)
307
+ local = strings.TrimPrefix(local, "/")
308
+ }
309
+ matches = append(matches, boundaryFile{
310
+ Element: elem,
311
+ Type: elem.Type,
312
+ Path: normalized,
313
+ RelativePath: rel,
314
+ RootPath: root,
315
+ LocalPath: local,
316
+ Entry: elem.Entry,
317
+ Private: elem.Private,
318
+ })
319
+ }
320
+ if len(matches) == 0 {
321
+ return nil
322
+ }
323
+ sort.Slice(matches, func(i, j int) bool {
324
+ return len(matches[i].RootPath) > len(matches[j].RootPath)
325
+ })
326
+ return &matches[0]
327
+ }
328
+
329
+ func evaluateBoundaryPolicy(opts boundariesOptions, fromType, targetType string) (string, *boundaryPolicyRule) {
330
+ defaultPolicy := opts.Default
331
+ if defaultPolicy == "" {
332
+ defaultPolicy = "allow"
333
+ }
334
+ for i := range opts.Rules {
335
+ rule := &opts.Rules[i]
336
+ if len(rule.From) > 0 && !matchAnyBoundaryPattern(rule.From, fromType) {
337
+ continue
338
+ }
339
+ if len(rule.Disallow) > 0 && matchAnyBoundaryPattern(rule.Disallow, targetType) {
340
+ return "disallow", rule
341
+ }
342
+ if len(rule.Allow) > 0 {
343
+ if matchAnyBoundaryPattern(rule.Allow, targetType) {
344
+ return "allow", rule
345
+ }
346
+ return "disallow", rule
347
+ }
348
+ }
349
+ return defaultPolicy, nil
350
+ }
351
+
352
+ func resolveBoundaryImport(sourceFileName, specifier string) (string, bool) {
353
+ if !isRelativeBoundarySpecifier(specifier) {
354
+ return "", false
355
+ }
356
+ base := filepath.Dir(sourceFileName)
357
+ target := filepath.Clean(filepath.Join(base, filepath.FromSlash(specifier)))
358
+ candidates := []string{target}
359
+ if filepath.Ext(target) == "" {
360
+ for _, ext := range []string{".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs"} {
361
+ candidates = append(candidates, target+ext)
362
+ }
363
+ for _, ext := range []string{".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs"} {
364
+ candidates = append(candidates, filepath.Join(target, "index"+ext))
365
+ }
366
+ }
367
+ for _, candidate := range candidates {
368
+ if info, err := os.Stat(candidate); err == nil && !info.IsDir() {
369
+ abs, err := filepath.Abs(candidate)
370
+ if err == nil {
371
+ return abs, true
372
+ }
373
+ return candidate, true
374
+ }
375
+ }
376
+ return "", false
377
+ }
378
+
379
+ func reportBoundaryDependency(ctx *Context, dep boundaryDependency, message string) {
380
+ if dep.node != nil {
381
+ ctx.Report(dep.node, message)
382
+ return
383
+ }
384
+ ctx.ReportRange(0, 1, message)
385
+ }
386
+
387
+ func matchBoundaryElementLocalPattern(patterns boundaryStringList, file *boundaryFile) bool {
388
+ if file == nil {
389
+ return false
390
+ }
391
+ for _, pattern := range patterns {
392
+ if boundaryPatternMatch(pattern, file.LocalPath) || boundaryPatternMatch(pattern, filepath.Base(file.LocalPath)) || boundaryPatternMatch(pattern, file.RelativePath) {
393
+ return true
394
+ }
395
+ }
396
+ return false
397
+ }
398
+
399
+ func matchAnyBoundaryPattern(patterns boundaryStringList, candidates ...string) bool {
400
+ for _, pattern := range patterns {
401
+ for _, candidate := range candidates {
402
+ if boundaryPatternMatch(pattern, candidate) {
403
+ return true
404
+ }
405
+ }
406
+ }
407
+ return false
408
+ }
409
+
410
+ func boundaryRelativeMatch(pattern, fileName string) (string, bool) {
411
+ for _, candidate := range boundaryPathCandidates(fileName) {
412
+ if boundaryPatternMatch(pattern, candidate) {
413
+ return candidate, true
414
+ }
415
+ }
416
+ return "", false
417
+ }
418
+
419
+ func boundaryPatternMatch(pattern, candidate string) bool {
420
+ pattern = strings.TrimPrefix(normalizeBoundaryPath(pattern), "./")
421
+ candidate = strings.TrimPrefix(normalizeBoundaryPath(candidate), "./")
422
+ if pattern == "" || candidate == "" {
423
+ return false
424
+ }
425
+ re, err := regexp.Compile("^" + regexp.QuoteMeta(pattern) + "$")
426
+ if err != nil {
427
+ return false
428
+ }
429
+ expr := re.String()
430
+ expr = strings.ReplaceAll(expr, `\*\*`, ".*")
431
+ expr = strings.ReplaceAll(expr, `\*`, `[^/]*`)
432
+ expr = strings.ReplaceAll(expr, `\?`, `[^/]`)
433
+ re, err = regexp.Compile(expr)
434
+ if err != nil {
435
+ return false
436
+ }
437
+ return re.MatchString(candidate)
438
+ }
439
+
440
+ func boundaryPathCandidates(path string) []string {
441
+ normalized := strings.TrimPrefix(normalizeBoundaryPath(path), "/")
442
+ candidates := []string{normalized}
443
+ if cwd, err := os.Getwd(); err == nil {
444
+ if rel, err := filepath.Rel(cwd, path); err == nil && !strings.HasPrefix(rel, "..") {
445
+ candidates = append(candidates, normalizeBoundaryPath(rel))
446
+ }
447
+ }
448
+ parts := strings.Split(normalized, "/")
449
+ for i := 1; i < len(parts); i++ {
450
+ candidates = append(candidates, strings.Join(parts[i:], "/"))
451
+ }
452
+ return uniqueBoundaryStrings(candidates)
453
+ }
454
+
455
+ func boundaryElementRoot(pattern, matched string) string {
456
+ pattern = strings.TrimPrefix(normalizeBoundaryPath(pattern), "./")
457
+ wildcard := len(pattern)
458
+ for _, token := range []string{"*", "?"} {
459
+ if idx := strings.Index(pattern, token); idx >= 0 && idx < wildcard {
460
+ wildcard = idx
461
+ }
462
+ }
463
+ root := strings.TrimSuffix(pattern[:wildcard], "/")
464
+ if root == pattern {
465
+ root = filepath.ToSlash(filepath.Dir(root))
466
+ if root == "." {
467
+ root = ""
468
+ }
469
+ }
470
+ if root != "" {
471
+ return root
472
+ }
473
+ if slash := strings.LastIndex(matched, "/"); slash >= 0 {
474
+ return matched[:slash]
475
+ }
476
+ return ""
477
+ }
478
+
479
+ func boundaryPackageName(specifier string) string {
480
+ if strings.HasPrefix(specifier, "@") {
481
+ parts := strings.Split(specifier, "/")
482
+ if len(parts) >= 2 {
483
+ return parts[0] + "/" + parts[1]
484
+ }
485
+ return specifier
486
+ }
487
+ if idx := strings.Index(specifier, "/"); idx >= 0 {
488
+ return specifier[:idx]
489
+ }
490
+ return specifier
491
+ }
492
+
493
+ func boundaryDisplayPath(path string) string {
494
+ candidates := boundaryPathCandidates(path)
495
+ if len(candidates) == 0 {
496
+ return normalizeBoundaryPath(path)
497
+ }
498
+ return candidates[0]
499
+ }
500
+
501
+ func normalizeBoundaryPath(path string) string {
502
+ return filepath.ToSlash(filepath.Clean(path))
503
+ }
504
+
505
+ func isRelativeBoundarySpecifier(specifier string) bool {
506
+ return specifier == "." || specifier == ".." || strings.HasPrefix(specifier, "./") || strings.HasPrefix(specifier, "../")
507
+ }
508
+
509
+ func uniqueBoundaryStrings(values []string) []string {
510
+ seen := map[string]struct{}{}
511
+ out := []string{}
512
+ for _, value := range values {
513
+ if value == "" {
514
+ continue
515
+ }
516
+ if _, ok := seen[value]; ok {
517
+ continue
518
+ }
519
+ seen[value] = struct{}{}
520
+ out = append(out, value)
521
+ }
522
+ return out
523
+ }
524
+
525
+ func init() {
526
+ Register(boundariesElementTypes{})
527
+ Register(boundariesExternal{})
528
+ Register(boundariesEntryPoint{})
529
+ Register(boundariesNoPrivate{})
530
+ Register(boundariesNoUnknown{})
531
+ Register(boundariesDependencies{})
532
+ }
@@ -0,0 +1,133 @@
1
+ // camelcase reports declaration names that are neither camelCase nor
2
+ // PascalCase. snake_case bindings are the canonical failure: the
3
+ // underscore between two letters signals a non-JavaScript naming
4
+ // convention and the rule pushes authors back to the language norm.
5
+ // https://eslint.org/docs/latest/rules/camelcase
6
+ //
7
+ // Conservative baseline: only the four declaration kinds the ESLint
8
+ // rule documents as in-scope are inspected — variable, function, class,
9
+ // and parameter declarations. Each is checked through its `Name()`
10
+ // accessor so destructuring patterns and computed property names are
11
+ // skipped automatically (they return non-Identifier nodes). Leading
12
+ // and trailing underscores plus a single all-uppercase form
13
+ // (`MAX_VALUE`) are tolerated because ESLint exempts them too.
14
+ package linthost
15
+
16
+ import (
17
+ shimast "github.com/microsoft/typescript-go/shim/ast"
18
+ )
19
+
20
+ type camelcase struct{}
21
+
22
+ func (camelcase) Name() string { return "camelcase" }
23
+ func (camelcase) Visits() []shimast.Kind {
24
+ return []shimast.Kind{
25
+ shimast.KindVariableDeclaration,
26
+ shimast.KindParameter,
27
+ shimast.KindFunctionDeclaration,
28
+ shimast.KindClassDeclaration,
29
+ }
30
+ }
31
+ func (camelcase) Check(ctx *Context, node *shimast.Node) {
32
+ var nameNode *shimast.Node
33
+ switch node.Kind {
34
+ case shimast.KindVariableDeclaration:
35
+ decl := node.AsVariableDeclaration()
36
+ if decl == nil {
37
+ return
38
+ }
39
+ nameNode = decl.Name()
40
+ case shimast.KindParameter:
41
+ decl := node.AsParameterDeclaration()
42
+ if decl == nil {
43
+ return
44
+ }
45
+ nameNode = decl.Name()
46
+ case shimast.KindFunctionDeclaration:
47
+ decl := node.AsFunctionDeclaration()
48
+ if decl == nil {
49
+ return
50
+ }
51
+ nameNode = decl.Name()
52
+ case shimast.KindClassDeclaration:
53
+ decl := node.AsClassDeclaration()
54
+ if decl == nil {
55
+ return
56
+ }
57
+ nameNode = decl.Name()
58
+ }
59
+ name := identifierText(nameNode)
60
+ if name == "" {
61
+ return
62
+ }
63
+ if isCamelOrPascalCaseName(name) {
64
+ return
65
+ }
66
+ ctx.Report(nameNode, "Identifier '"+name+"' is not in camelCase.")
67
+ }
68
+
69
+ // isCamelOrPascalCaseName reports whether `name` matches the convention
70
+ // the rule accepts. The canonical violation is a snake_case binding —
71
+ // an underscore wedged between two letters — so the predicate inspects
72
+ // the trimmed interior of the name. Leading and trailing underscores
73
+ // are stripped first (`_foo`, `foo__`) because ESLint deliberately
74
+ // allows the private-prefix and trailing-underscore conventions. An
75
+ // all-uppercase residue (`MAX_VALUE` → `MAX_VALUE`) is treated as a
76
+ // SCREAMING_SNAKE constant and accepted; everything else with an
77
+ // interior underscore is reported.
78
+ func isCamelOrPascalCaseName(name string) bool {
79
+ if name == "" {
80
+ return true
81
+ }
82
+ trimmed := trimUnderscores(name)
83
+ if trimmed == "" {
84
+ return true
85
+ }
86
+ if !containsUnderscore(trimmed) {
87
+ return true
88
+ }
89
+ return isAllUpperOrUnderscore(trimmed)
90
+ }
91
+
92
+ func trimUnderscores(s string) string {
93
+ start, end := 0, len(s)
94
+ for start < end && s[start] == '_' {
95
+ start++
96
+ }
97
+ for end > start && s[end-1] == '_' {
98
+ end--
99
+ }
100
+ return s[start:end]
101
+ }
102
+
103
+ func containsUnderscore(s string) bool {
104
+ for i := 0; i < len(s); i++ {
105
+ if s[i] == '_' {
106
+ return true
107
+ }
108
+ }
109
+ return false
110
+ }
111
+
112
+ // isAllUpperOrUnderscore returns true when every character is either an
113
+ // uppercase ASCII letter, a digit, or an underscore. Lowercase letters
114
+ // disqualify the string and force the rule to report.
115
+ func isAllUpperOrUnderscore(s string) bool {
116
+ hasUpper := false
117
+ for i := 0; i < len(s); i++ {
118
+ ch := s[i]
119
+ switch {
120
+ case ch >= 'A' && ch <= 'Z':
121
+ hasUpper = true
122
+ case ch >= '0' && ch <= '9':
123
+ case ch == '_':
124
+ default:
125
+ return false
126
+ }
127
+ }
128
+ return hasUpper
129
+ }
130
+
131
+ func init() {
132
+ Register(camelcase{})
133
+ }