@ttsc/lint 0.14.0-dev.20260529.1 → 0.14.0

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 (380) hide show
  1. package/README.md +85 -87
  2. package/lib/defaultFormat.d.ts +10 -6
  3. package/lib/defaultFormat.js +10 -6
  4. package/lib/defaultFormat.js.map +1 -1
  5. package/lib/structures/ITtscLintConfig.d.ts +5 -5
  6. package/lib/structures/TtscLintRuleSetting.d.ts +19 -19
  7. package/lib/structures/{ITtscLintFormat.d.ts → format/ITtscLintFormat.d.ts} +45 -70
  8. package/lib/structures/format/ITtscLintFormat.js.map +1 -0
  9. package/lib/structures/format/ITtscLintFormatJsDoc.d.ts +15 -0
  10. package/lib/structures/format/ITtscLintFormatJsDoc.js +3 -0
  11. package/lib/structures/format/ITtscLintFormatJsDoc.js.map +1 -0
  12. package/lib/structures/format/ITtscLintFormatSortImports.d.ts +54 -0
  13. package/lib/structures/format/ITtscLintFormatSortImports.js +3 -0
  14. package/lib/structures/format/ITtscLintFormatSortImports.js.map +1 -0
  15. package/lib/structures/format/index.d.ts +3 -0
  16. package/lib/structures/format/index.js +20 -0
  17. package/lib/structures/format/index.js.map +1 -0
  18. package/lib/structures/index.d.ts +1 -1
  19. package/lib/structures/index.js +1 -1
  20. package/lib/structures/index.js.map +1 -1
  21. package/lib/structures/rules/ITtscLintBoundariesRuleOptions.d.ts +18 -27
  22. package/lib/structures/rules/ITtscLintBoundariesRuleOptions.js +4 -5
  23. package/lib/structures/rules/ITtscLintBoundariesRuleOptions.js.map +1 -1
  24. package/lib/structures/rules/ITtscLintBoundariesRules.d.ts +29 -33
  25. package/lib/structures/rules/ITtscLintContributorRules.d.ts +6 -7
  26. package/lib/structures/rules/ITtscLintCoreRules.d.ts +380 -408
  27. package/lib/structures/rules/ITtscLintCypressRuleOptions.d.ts +5 -5
  28. package/lib/structures/rules/ITtscLintCypressRuleOptions.js +2 -2
  29. package/lib/structures/rules/ITtscLintCypressRules.d.ts +34 -38
  30. package/lib/structures/rules/ITtscLintFunctionalRuleOptions.d.ts +21 -24
  31. package/lib/structures/rules/ITtscLintFunctionalRuleOptions.js +2 -2
  32. package/lib/structures/rules/ITtscLintFunctionalRules.d.ts +51 -56
  33. package/lib/structures/rules/ITtscLintJestRules.d.ts +63 -74
  34. package/lib/structures/rules/ITtscLintJsdocRules.d.ts +47 -54
  35. package/lib/structures/rules/ITtscLintJsxA11yRules.d.ts +94 -102
  36. package/lib/structures/rules/ITtscLintNextjsRules.d.ts +50 -55
  37. package/lib/structures/rules/ITtscLintPlaywrightRules.d.ts +104 -122
  38. package/lib/structures/rules/ITtscLintPromiseRules.d.ts +62 -71
  39. package/lib/structures/rules/ITtscLintReactPerfRuleOptions.d.ts +4 -4
  40. package/lib/structures/rules/ITtscLintReactPerfRules.d.ts +17 -19
  41. package/lib/structures/rules/ITtscLintReactRuleOptions.d.ts +8 -10
  42. package/lib/structures/rules/ITtscLintReactRuleOptions.js +1 -2
  43. package/lib/structures/rules/ITtscLintReactRuleOptions.js.map +1 -1
  44. package/lib/structures/rules/ITtscLintReactRules.d.ts +91 -104
  45. package/lib/structures/rules/ITtscLintRegexpRules.d.ts +46 -54
  46. package/lib/structures/rules/ITtscLintRuleOptionsMap.d.ts +7 -8
  47. package/lib/structures/rules/ITtscLintSecurityRules.d.ts +45 -52
  48. package/lib/structures/rules/ITtscLintSolidRules.d.ts +53 -56
  49. package/lib/structures/rules/ITtscLintStorybookRuleOptions.d.ts +3 -4
  50. package/lib/structures/rules/ITtscLintStorybookRules.d.ts +60 -69
  51. package/lib/structures/rules/ITtscLintTanstackQueryRules.d.ts +31 -37
  52. package/lib/structures/rules/ITtscLintTestingLibraryRuleOptions.d.ts +2 -3
  53. package/lib/structures/rules/ITtscLintTestingLibraryRules.d.ts +102 -119
  54. package/lib/structures/rules/ITtscLintTypeScriptRules.d.ts +460 -518
  55. package/lib/structures/rules/ITtscLintVitestRules.d.ts +43 -51
  56. package/linthost/config.go +89 -72
  57. package/linthost/config_format.go +265 -99
  58. package/linthost/directives.go +5 -1
  59. package/linthost/display_width.go +72 -0
  60. package/linthost/fix.go +26 -1
  61. package/linthost/format.go +222 -25
  62. package/linthost/format_editor_settings.go +262 -0
  63. package/linthost/lsp.go +8 -4
  64. package/linthost/print_dispatch.go +3 -0
  65. package/linthost/print_doc.go +13 -0
  66. package/linthost/print_engine.go +68 -11
  67. package/linthost/print_nodes_array.go +108 -5
  68. package/linthost/print_nodes_call.go +515 -74
  69. package/linthost/print_nodes_function.go +25 -0
  70. package/linthost/print_nodes_imports.go +47 -14
  71. package/linthost/print_nodes_list.go +191 -8
  72. package/linthost/print_nodes_object.go +12 -6
  73. package/linthost/print_nodes_ternary.go +106 -0
  74. package/linthost/rules_boundaries.go +400 -400
  75. package/linthost/rules_camelcase.go +81 -81
  76. package/linthost/rules_complexity.go +52 -51
  77. package/linthost/rules_consistent_return.go +81 -81
  78. package/linthost/rules_core_extra.go +472 -472
  79. package/linthost/rules_curly.go +43 -43
  80. package/linthost/rules_default_case.go +15 -15
  81. package/linthost/rules_default_case_last.go +22 -22
  82. package/linthost/rules_format_arrow_parens.go +167 -0
  83. package/linthost/rules_format_bracket_spacing.go +117 -0
  84. package/linthost/rules_format_clause_join.go +172 -0
  85. package/linthost/rules_format_declaration_header.go +664 -0
  86. package/linthost/rules_format_indent.go +616 -0
  87. package/linthost/rules_format_jsdoc.go +4 -4
  88. package/linthost/rules_format_orphan_semi.go +106 -0
  89. package/linthost/rules_format_parameter_properties.go +175 -0
  90. package/linthost/rules_format_print_width.go +185 -69
  91. package/linthost/rules_format_quote_props.go +169 -0
  92. package/linthost/rules_format_quotes.go +75 -29
  93. package/linthost/rules_format_semi.go +185 -10
  94. package/linthost/rules_format_sort_imports.go +456 -121
  95. package/linthost/rules_format_statement_split.go +368 -0
  96. package/linthost/rules_format_ternary_nullish_parens.go +77 -0
  97. package/linthost/rules_format_trailing_comma.go +21 -2
  98. package/linthost/rules_format_whitespace.go +336 -0
  99. package/linthost/rules_functional.go +688 -688
  100. package/linthost/rules_gap.go +146 -11
  101. package/linthost/rules_grouped_accessor_pairs.go +60 -60
  102. package/linthost/rules_guard_for_in.go +122 -122
  103. package/linthost/rules_id_length.go +44 -44
  104. package/linthost/rules_imports.go +11 -3
  105. package/linthost/rules_init_declarations.go +25 -25
  106. package/linthost/rules_jsx_a11y.go +844 -844
  107. package/linthost/rules_max_classes_per_file.go +24 -24
  108. package/linthost/rules_max_depth.go +43 -43
  109. package/linthost/rules_max_lines.go +53 -53
  110. package/linthost/rules_max_lines_per_function.go +28 -28
  111. package/linthost/rules_max_nested_callbacks.go +26 -26
  112. package/linthost/rules_max_params.go +20 -20
  113. package/linthost/rules_max_statements.go +29 -29
  114. package/linthost/rules_nextjs.go +5 -5
  115. package/linthost/rules_no_else_return.go +38 -38
  116. package/linthost/rules_no_empty_named_blocks.go +45 -45
  117. package/linthost/rules_no_import_assign.go +96 -96
  118. package/linthost/rules_no_invalid_this.go +19 -19
  119. package/linthost/rules_no_loop_func.go +43 -43
  120. package/linthost/rules_no_magic_numbers.go +60 -60
  121. package/linthost/rules_no_mixed_operators.go +44 -44
  122. package/linthost/rules_no_param_reassign.go +64 -64
  123. package/linthost/rules_no_restricted_imports.go +45 -45
  124. package/linthost/rules_no_restricted_syntax.go +17 -17
  125. package/linthost/rules_no_shadow.go +112 -112
  126. package/linthost/rules_no_unreachable.go +36 -36
  127. package/linthost/rules_no_useless_assignment.go +79 -79
  128. package/linthost/rules_no_useless_constructor.go +167 -167
  129. package/linthost/rules_no_useless_return.go +28 -28
  130. package/linthost/rules_prefer_arrow_callback.go +74 -74
  131. package/linthost/rules_prefer_destructuring.go +61 -61
  132. package/linthost/rules_prefer_named_capture_group.go +87 -87
  133. package/linthost/rules_prefer_rest_params.go +61 -61
  134. package/linthost/rules_promise.go +800 -800
  135. package/linthost/rules_react.go +600 -600
  136. package/linthost/rules_react_extras.go +162 -162
  137. package/linthost/rules_react_hooks.go +2 -2
  138. package/linthost/rules_react_perf.go +231 -231
  139. package/linthost/rules_regexp.go +293 -293
  140. package/linthost/rules_security.go +613 -613
  141. package/linthost/rules_sort_imports.go +37 -37
  142. package/linthost/rules_sort_keys.go +88 -88
  143. package/linthost/rules_suggestions.go +13 -0
  144. package/linthost/rules_ts.go +2 -2
  145. package/linthost/rules_ts_async.go +247 -247
  146. package/linthost/rules_ts_class_literal_property_style.go +64 -64
  147. package/linthost/rules_ts_consistent_type_exports.go +209 -209
  148. package/linthost/rules_ts_explicit_function_return_type.go +35 -35
  149. package/linthost/rules_ts_extra.go +6 -2
  150. package/linthost/rules_ts_no_base_to_string.go +140 -140
  151. package/linthost/rules_ts_no_confusing_void.go +28 -28
  152. package/linthost/rules_ts_no_deprecated.go +110 -110
  153. package/linthost/rules_ts_no_for_in_array.go +45 -45
  154. package/linthost/rules_ts_no_magic_numbers.go +67 -67
  155. package/linthost/rules_ts_no_meaningless_void_operator.go +44 -44
  156. package/linthost/rules_ts_no_misused_spread.go +64 -64
  157. package/linthost/rules_ts_no_redundant_type_constituents.go +72 -72
  158. package/linthost/rules_ts_no_restricted_types.go +28 -28
  159. package/linthost/rules_ts_no_unnecessary_boolean_literal_compare.go +87 -87
  160. package/linthost/rules_ts_no_unnecessary_condition.go +184 -184
  161. package/linthost/rules_ts_no_unnecessary_qualifier.go +72 -72
  162. package/linthost/rules_ts_no_unnecessary_template_expression.go +120 -120
  163. package/linthost/rules_ts_no_unnecessary_type_arguments.go +171 -171
  164. package/linthost/rules_ts_no_unnecessary_type_assertion.go +90 -90
  165. package/linthost/rules_ts_no_unsafe_argument.go +50 -50
  166. package/linthost/rules_ts_no_unsafe_assignment.go +60 -60
  167. package/linthost/rules_ts_no_unsafe_call.go +40 -40
  168. package/linthost/rules_ts_no_unsafe_enum_comparison.go +147 -147
  169. package/linthost/rules_ts_no_unsafe_member_access.go +29 -29
  170. package/linthost/rules_ts_no_unsafe_return.go +64 -64
  171. package/linthost/rules_ts_no_unsafe_unary_minus.go +42 -42
  172. package/linthost/rules_ts_no_useless_constructor.go +20 -20
  173. package/linthost/rules_ts_non_nullable_type_assertion_style.go +60 -60
  174. package/linthost/rules_ts_parameter_properties.go +10 -10
  175. package/linthost/rules_ts_prefer_find.go +116 -116
  176. package/linthost/rules_ts_prefer_includes.go +173 -173
  177. package/linthost/rules_ts_prefer_nullish_coalescing.go +54 -54
  178. package/linthost/rules_ts_prefer_optional_chain.go +156 -156
  179. package/linthost/rules_ts_prefer_promise_reject_errors.go +104 -104
  180. package/linthost/rules_ts_prefer_readonly.go +31 -31
  181. package/linthost/rules_ts_prefer_reduce_type_parameter.go +74 -74
  182. package/linthost/rules_ts_prefer_regexp_exec.go +69 -69
  183. package/linthost/rules_ts_prefer_return_this_type.go +79 -79
  184. package/linthost/rules_ts_prefer_string_starts_ends_with.go +237 -237
  185. package/linthost/rules_ts_promise_function_async.go +41 -41
  186. package/linthost/rules_ts_related_getter_setter_pairs.go +61 -61
  187. package/linthost/rules_ts_require_array_sort_compare.go +58 -58
  188. package/linthost/rules_ts_restrict_plus_operands.go +82 -82
  189. package/linthost/rules_ts_restrict_template_expressions.go +50 -50
  190. package/linthost/rules_ts_simple.go +249 -249
  191. package/linthost/rules_ts_sort_type_constituents.go +88 -88
  192. package/linthost/rules_ts_strict_boolean_expressions.go +103 -103
  193. package/linthost/rules_ts_switch_exhaustiveness_check.go +90 -90
  194. package/linthost/rules_ts_unbound_method.go +65 -65
  195. package/linthost/rules_tsdoc.go +88 -88
  196. package/linthost/rules_unicorn_better_regex.go +1 -1
  197. package/linthost/rules_unicorn_catch_error_name.go +19 -19
  198. package/linthost/rules_unicorn_consistent_assert.go +20 -20
  199. package/linthost/rules_unicorn_consistent_date_clone.go +27 -27
  200. package/linthost/rules_unicorn_consistent_destructuring.go +3 -3
  201. package/linthost/rules_unicorn_consistent_empty_array_spread.go +34 -34
  202. package/linthost/rules_unicorn_consistent_existence_index_check.go +42 -42
  203. package/linthost/rules_unicorn_consistent_function_scoping.go +3 -3
  204. package/linthost/rules_unicorn_consistent_template_literal_escape.go +3 -3
  205. package/linthost/rules_unicorn_custom_error_definition.go +92 -92
  206. package/linthost/rules_unicorn_empty_brace_spaces.go +47 -47
  207. package/linthost/rules_unicorn_error_message.go +34 -34
  208. package/linthost/rules_unicorn_escape_case.go +14 -14
  209. package/linthost/rules_unicorn_expiring_todo_comments.go +36 -36
  210. package/linthost/rules_unicorn_explicit_length_check.go +51 -51
  211. package/linthost/rules_unicorn_filename_case.go +1 -1
  212. package/linthost/rules_unicorn_import_style.go +1 -1
  213. package/linthost/rules_unicorn_isolated_functions.go +2 -2
  214. package/linthost/rules_unicorn_new_for_builtins.go +49 -49
  215. package/linthost/rules_unicorn_no_abusive_eslint_disable.go +31 -31
  216. package/linthost/rules_unicorn_no_accessor_recursion.go +69 -69
  217. package/linthost/rules_unicorn_no_anonymous_default_export.go +40 -40
  218. package/linthost/rules_unicorn_no_array_callback_reference.go +33 -33
  219. package/linthost/rules_unicorn_no_array_for_each.go +14 -14
  220. package/linthost/rules_unicorn_no_array_method_this_argument.go +29 -29
  221. package/linthost/rules_unicorn_no_array_reduce.go +15 -15
  222. package/linthost/rules_unicorn_no_array_reverse.go +17 -17
  223. package/linthost/rules_unicorn_no_array_sort.go +17 -17
  224. package/linthost/rules_unicorn_no_await_expression_member.go +12 -12
  225. package/linthost/rules_unicorn_no_await_in_promise_methods.go +38 -38
  226. package/linthost/rules_unicorn_no_console_spaces.go +30 -30
  227. package/linthost/rules_unicorn_no_document_cookie.go +13 -13
  228. package/linthost/rules_unicorn_no_empty_file.go +16 -16
  229. package/linthost/rules_unicorn_no_for_loop.go +58 -58
  230. package/linthost/rules_unicorn_no_hex_escape.go +11 -11
  231. package/linthost/rules_unicorn_no_immediate_mutation.go +55 -55
  232. package/linthost/rules_unicorn_no_instanceof_builtins.go +34 -34
  233. package/linthost/rules_unicorn_no_invalid_fetch_options.go +52 -52
  234. package/linthost/rules_unicorn_no_invalid_remove_event_listener.go +25 -25
  235. package/linthost/rules_unicorn_no_keyword_prefix.go +56 -56
  236. package/linthost/rules_unicorn_no_lonely_if.go +21 -21
  237. package/linthost/rules_unicorn_no_magic_array_flat_depth.go +22 -22
  238. package/linthost/rules_unicorn_no_named_default.go +25 -25
  239. package/linthost/rules_unicorn_no_negated_condition.go +54 -54
  240. package/linthost/rules_unicorn_no_negation_in_equality_check.go +23 -23
  241. package/linthost/rules_unicorn_no_nested_ternary.go +15 -15
  242. package/linthost/rules_unicorn_no_new_array.go +5 -5
  243. package/linthost/rules_unicorn_no_new_buffer.go +5 -5
  244. package/linthost/rules_unicorn_no_null.go +2 -2
  245. package/linthost/rules_unicorn_no_object_as_default_parameter.go +19 -19
  246. package/linthost/rules_unicorn_no_process_exit.go +17 -17
  247. package/linthost/rules_unicorn_no_single_promise_in_promise_methods.go +29 -29
  248. package/linthost/rules_unicorn_no_static_only_class.go +27 -27
  249. package/linthost/rules_unicorn_no_thenable.go +47 -47
  250. package/linthost/rules_unicorn_no_this_assignment.go +10 -10
  251. package/linthost/rules_unicorn_no_typeof_undefined.go +31 -31
  252. package/linthost/rules_unicorn_no_unnecessary_array_flat_depth.go +23 -23
  253. package/linthost/rules_unicorn_no_unnecessary_array_splice_count.go +37 -37
  254. package/linthost/rules_unicorn_no_unnecessary_await.go +24 -24
  255. package/linthost/rules_unicorn_no_unnecessary_slice_end.go +22 -22
  256. package/linthost/rules_unicorn_no_unreadable_array_destructuring.go +67 -67
  257. package/linthost/rules_unicorn_no_unreadable_iife.go +22 -22
  258. package/linthost/rules_unicorn_no_useless_collection_argument.go +34 -34
  259. package/linthost/rules_unicorn_no_useless_error_capture_stack_trace.go +18 -18
  260. package/linthost/rules_unicorn_no_useless_fallback_in_spread.go +49 -49
  261. package/linthost/rules_unicorn_no_useless_iterator_to_array.go +41 -41
  262. package/linthost/rules_unicorn_no_useless_length_check.go +82 -82
  263. package/linthost/rules_unicorn_no_useless_promise_resolve_reject.go +42 -42
  264. package/linthost/rules_unicorn_no_useless_spread.go +38 -38
  265. package/linthost/rules_unicorn_no_useless_switch_case.go +29 -29
  266. package/linthost/rules_unicorn_no_useless_undefined.go +25 -25
  267. package/linthost/rules_unicorn_no_zero_fractions.go +17 -17
  268. package/linthost/rules_unicorn_number_literal_case.go +33 -33
  269. package/linthost/rules_unicorn_numeric_separators_style.go +36 -36
  270. package/linthost/rules_unicorn_prefer_add_event_listener.go +30 -30
  271. package/linthost/rules_unicorn_prefer_array_find.go +27 -27
  272. package/linthost/rules_unicorn_prefer_array_flat.go +25 -25
  273. package/linthost/rules_unicorn_prefer_array_flat_map.go +37 -37
  274. package/linthost/rules_unicorn_prefer_array_index_of.go +108 -108
  275. package/linthost/rules_unicorn_prefer_array_some.go +43 -43
  276. package/linthost/rules_unicorn_prefer_at.go +42 -42
  277. package/linthost/rules_unicorn_prefer_bigint_literals.go +42 -42
  278. package/linthost/rules_unicorn_prefer_blob_reading_methods.go +15 -15
  279. package/linthost/rules_unicorn_prefer_class_fields.go +57 -57
  280. package/linthost/rules_unicorn_prefer_classlist_toggle.go +76 -76
  281. package/linthost/rules_unicorn_prefer_code_point.go +21 -21
  282. package/linthost/rules_unicorn_prefer_date_now.go +47 -47
  283. package/linthost/rules_unicorn_prefer_default_parameters.go +96 -96
  284. package/linthost/rules_unicorn_prefer_dom_node_append.go +14 -14
  285. package/linthost/rules_unicorn_prefer_dom_node_dataset.go +27 -27
  286. package/linthost/rules_unicorn_prefer_dom_node_remove.go +17 -17
  287. package/linthost/rules_unicorn_prefer_dom_node_text_content.go +11 -11
  288. package/linthost/rules_unicorn_prefer_event_target.go +10 -10
  289. package/linthost/rules_unicorn_prefer_export_from.go +99 -99
  290. package/linthost/rules_unicorn_prefer_global_this.go +91 -91
  291. package/linthost/rules_unicorn_prefer_import_meta_properties.go +38 -38
  292. package/linthost/rules_unicorn_prefer_includes.go +108 -108
  293. package/linthost/rules_unicorn_prefer_json_parse_buffer.go +37 -37
  294. package/linthost/rules_unicorn_prefer_keyboard_event_key.go +10 -10
  295. package/linthost/rules_unicorn_prefer_logical_operator_over_ternary.go +20 -20
  296. package/linthost/rules_unicorn_prefer_math_min_max.go +33 -33
  297. package/linthost/rules_unicorn_prefer_math_trunc.go +32 -32
  298. package/linthost/rules_unicorn_prefer_modern_dom_apis.go +18 -18
  299. package/linthost/rules_unicorn_prefer_modern_math_apis.go +38 -38
  300. package/linthost/rules_unicorn_prefer_module.go +22 -22
  301. package/linthost/rules_unicorn_prefer_native_coercion_functions.go +73 -73
  302. package/linthost/rules_unicorn_prefer_negative_index.go +46 -46
  303. package/linthost/rules_unicorn_prefer_node_protocol.go +90 -90
  304. package/linthost/rules_unicorn_prefer_number_properties.go +57 -57
  305. package/linthost/rules_unicorn_prefer_object_from_entries.go +26 -26
  306. package/linthost/rules_unicorn_prefer_optional_catch_binding.go +24 -24
  307. package/linthost/rules_unicorn_prefer_prototype_methods.go +25 -25
  308. package/linthost/rules_unicorn_prefer_query_selector.go +25 -25
  309. package/linthost/rules_unicorn_prefer_reflect_apply.go +10 -10
  310. package/linthost/rules_unicorn_prefer_regexp_test_rule.go +47 -47
  311. package/linthost/rules_unicorn_prefer_response_static_json.go +26 -26
  312. package/linthost/rules_unicorn_prefer_set_has.go +16 -16
  313. package/linthost/rules_unicorn_prefer_set_size.go +22 -22
  314. package/linthost/rules_unicorn_prefer_simple_condition_first.go +3 -3
  315. package/linthost/rules_unicorn_prefer_single_call.go +59 -59
  316. package/linthost/rules_unicorn_prefer_spread.go +24 -24
  317. package/linthost/rules_unicorn_prefer_string_raw.go +12 -12
  318. package/linthost/rules_unicorn_prefer_string_replace_all.go +46 -46
  319. package/linthost/rules_unicorn_prefer_string_slice.go +17 -17
  320. package/linthost/rules_unicorn_prefer_string_starts_ends_with.go +104 -104
  321. package/linthost/rules_unicorn_prefer_string_trim_start_end.go +21 -21
  322. package/linthost/rules_unicorn_prefer_structured_clone.go +36 -36
  323. package/linthost/rules_unicorn_prefer_switch.go +65 -65
  324. package/linthost/rules_unicorn_prefer_ternary.go +35 -35
  325. package/linthost/rules_unicorn_prefer_top_level_await.go +34 -34
  326. package/linthost/rules_unicorn_prefer_type_error.go +84 -84
  327. package/linthost/rules_unicorn_prevent_abbreviations.go +68 -68
  328. package/linthost/rules_unicorn_relative_url_style.go +19 -19
  329. package/linthost/rules_unicorn_require_array_join_separator.go +18 -18
  330. package/linthost/rules_unicorn_require_module_attributes.go +25 -25
  331. package/linthost/rules_unicorn_require_module_specifiers.go +28 -28
  332. package/linthost/rules_unicorn_require_number_to_fixed_digits_argument.go +18 -18
  333. package/linthost/rules_unicorn_require_post_message_target_origin.go +18 -18
  334. package/linthost/rules_unicorn_string_content.go +1 -1
  335. package/linthost/rules_unicorn_switch_case_braces.go +16 -16
  336. package/linthost/rules_unicorn_switch_case_break_position.go +3 -3
  337. package/linthost/rules_unicorn_template_indent.go +1 -1
  338. package/linthost/rules_unicorn_text_encoding_identifier_case.go +36 -36
  339. package/linthost/rules_unicorn_throw_new_error.go +30 -30
  340. package/linthost/rules_var.go +273 -3
  341. package/package.json +3 -3
  342. package/src/defaultFormat.ts +11 -7
  343. package/src/structures/ITtscLintConfig.ts +5 -5
  344. package/src/structures/TtscLintRuleSetting.ts +19 -19
  345. package/src/structures/{ITtscLintFormat.ts → format/ITtscLintFormat.ts} +48 -75
  346. package/src/structures/format/ITtscLintFormatJsDoc.ts +16 -0
  347. package/src/structures/format/ITtscLintFormatSortImports.ts +62 -0
  348. package/src/structures/format/index.ts +3 -0
  349. package/src/structures/index.ts +1 -1
  350. package/src/structures/rules/ITtscLintBoundariesRuleOptions.ts +20 -31
  351. package/src/structures/rules/ITtscLintBoundariesRules.ts +32 -36
  352. package/src/structures/rules/ITtscLintContributorRules.ts +6 -7
  353. package/src/structures/rules/ITtscLintCoreRules.ts +380 -408
  354. package/src/structures/rules/ITtscLintCypressRuleOptions.ts +5 -5
  355. package/src/structures/rules/ITtscLintCypressRules.ts +34 -38
  356. package/src/structures/rules/ITtscLintFunctionalRuleOptions.ts +28 -41
  357. package/src/structures/rules/ITtscLintFunctionalRules.ts +51 -56
  358. package/src/structures/rules/ITtscLintJestRules.ts +63 -74
  359. package/src/structures/rules/ITtscLintJsdocRules.ts +47 -54
  360. package/src/structures/rules/ITtscLintJsxA11yRules.ts +94 -102
  361. package/src/structures/rules/ITtscLintNextjsRules.ts +50 -55
  362. package/src/structures/rules/ITtscLintPlaywrightRules.ts +104 -122
  363. package/src/structures/rules/ITtscLintPromiseRules.ts +62 -71
  364. package/src/structures/rules/ITtscLintReactPerfRuleOptions.ts +4 -4
  365. package/src/structures/rules/ITtscLintReactPerfRules.ts +17 -19
  366. package/src/structures/rules/ITtscLintReactRuleOptions.ts +8 -10
  367. package/src/structures/rules/ITtscLintReactRules.ts +91 -104
  368. package/src/structures/rules/ITtscLintRegexpRules.ts +46 -54
  369. package/src/structures/rules/ITtscLintRuleOptionsMap.ts +7 -8
  370. package/src/structures/rules/ITtscLintSecurityRules.ts +45 -52
  371. package/src/structures/rules/ITtscLintSolidRules.ts +53 -56
  372. package/src/structures/rules/ITtscLintStorybookRuleOptions.ts +3 -4
  373. package/src/structures/rules/ITtscLintStorybookRules.ts +60 -69
  374. package/src/structures/rules/ITtscLintTanstackQueryRules.ts +31 -37
  375. package/src/structures/rules/ITtscLintTestingLibraryRuleOptions.ts +2 -3
  376. package/src/structures/rules/ITtscLintTestingLibraryRules.ts +102 -119
  377. package/src/structures/rules/ITtscLintTypeScriptRules.ts +460 -518
  378. package/src/structures/rules/ITtscLintVitestRules.ts +43 -51
  379. package/lib/structures/ITtscLintFormat.js.map +0 -1
  380. /package/lib/structures/{ITtscLintFormat.js → format/ITtscLintFormat.js} +0 -0
@@ -0,0 +1,368 @@
1
+ package linthost
2
+
3
+ import (
4
+ "strings"
5
+
6
+ shimast "github.com/microsoft/typescript-go/shim/ast"
7
+ shimscanner "github.com/microsoft/typescript-go/shim/scanner"
8
+ )
9
+
10
+ // formatStatementSplit puts every statement in a statement list on its
11
+ // own physical line, mirroring Prettier's "one statement per line"
12
+ // layout. Prettier never leaves two statements sharing a source line,
13
+ // `const a = 1; let b = 2;` becomes two lines, and this rule is the
14
+ // always-on equivalent.
15
+ //
16
+ // Scope is every statement list the language produces: the SourceFile
17
+ // body, every Block and ModuleBlock, and the statement lists of `case`
18
+ // and `default` clauses. The rule registers for KindSourceFile and
19
+ // walks the subtree itself (like `format/sort-imports` and
20
+ // `format/jsdoc`), emitting one finding that may carry many TextEdits.
21
+ //
22
+ // Per-statement decision:
23
+ //
24
+ // 1. Find the statement's first non-trivia byte.
25
+ // 2. If it is the first non-whitespace byte on its physical line, the
26
+ // statement already starts its own line, abstain (that is
27
+ // `format/indent`'s surface).
28
+ // 3. Otherwise another statement precedes it on the same line. Replace
29
+ // the whitespace run immediately before the statement (back to the
30
+ // previous non-whitespace char) with EOL + indent(depth).
31
+ //
32
+ // Safety: abstain for a statement whose inter-statement gap holds a
33
+ // `//` or `/*` comment. Re-emitting EOL + indent over that gap would
34
+ // delete the comment, so the rule leaves the bytes untouched and a
35
+ // later pass (or the user) handles it.
36
+ //
37
+ // Idempotent: once each statement is alone on its line, step 2 abstains
38
+ // for all of them and the rule emits nothing.
39
+ type formatStatementSplit struct{}
40
+
41
+ // formatStatementSplitOptions carries the indentation + EOL settings the
42
+ // rule needs to synthesize the inserted line break. The JSON tags match
43
+ // the `format` block keys the config layer mirrors in (see
44
+ // `expandFormatBlock` in config_format.go).
45
+ type formatStatementSplitOptions struct {
46
+ TabWidth *int `json:"tabWidth"`
47
+ UseTabs *bool `json:"useTabs"`
48
+ EndOfLine *string `json:"endOfLine"`
49
+ }
50
+
51
+ func (formatStatementSplit) Name() string { return "format/statement-split" }
52
+ func (formatStatementSplit) IsFormat() bool { return true }
53
+ func (formatStatementSplit) Visits() []shimast.Kind {
54
+ return []shimast.Kind{shimast.KindSourceFile}
55
+ }
56
+
57
+ func (formatStatementSplit) Check(ctx *Context, node *shimast.Node) {
58
+ if ctx == nil || ctx.File == nil {
59
+ return
60
+ }
61
+ layout := loadFormatLayout(ctx)
62
+ src := ctx.File.Text()
63
+ var edits []TextEdit
64
+ forEachStatementInList(ctx.File, func(stmt *shimast.Node, depth int) {
65
+ // Empty statements (`;`) carry no content. Splitting each one onto
66
+ // its own line only multiplies blank-ish noise, so abstain.
67
+ if stmt.Kind == shimast.KindEmptyStatement {
68
+ return
69
+ }
70
+ start := shimscanner.SkipTrivia(src, stmt.Pos())
71
+ if start <= 0 || start > len(src) {
72
+ return
73
+ }
74
+ // Walk back over the whitespace run that precedes the statement.
75
+ ws := start
76
+ for ws > 0 && (src[ws-1] == ' ' || src[ws-1] == '\t') {
77
+ ws--
78
+ }
79
+ if ws == 0 || src[ws-1] == '\n' {
80
+ // First non-whitespace byte on its line already; that is
81
+ // `format/indent`'s job, not this rule's.
82
+ return
83
+ }
84
+ // Do not split a statement off a leading-semicolon ASI guard
85
+ // (`;(expr)`): the lone `;` before it is an empty-statement guard
86
+ // that format/orphan-semi intentionally merged onto this line, and
87
+ // re-splitting it would oscillate against that rule. The `;` is a
88
+ // guard (not a terminator like `foo();bar()`) when only whitespace
89
+ // precedes it back to the start of its line.
90
+ if src[ws-1] == ';' {
91
+ k := ws - 1
92
+ for k > 0 && (src[k-1] == ' ' || src[k-1] == '\t') {
93
+ k--
94
+ }
95
+ if k == 0 || src[k-1] == '\n' {
96
+ return
97
+ }
98
+ }
99
+ // A block that opens right after its own `case`/`default` label
100
+ // (`case 2: {`) is not sharing a line with a preceding statement;
101
+ // the only thing before it is the clause label, and Prettier keeps
102
+ // the brace on the label line. Abstain so the rule does not break
103
+ // the block off into `case 2:\n{`.
104
+ if stmt.Kind == shimast.KindBlock && firstStatementAfterCaseLabel(stmt) {
105
+ return
106
+ }
107
+ // The gap between the previous statement and this one must be pure
108
+ // whitespace. A `//` or `/*` anywhere from the previous statement's
109
+ // end to this one would be eaten by the replacement, so abstain. The
110
+ // scan starts at the previous statement boundary, not at `ws`: a
111
+ // comment is non-whitespace, so a scan that begins at `ws` (the end
112
+ // of the immediate whitespace run) can never see it.
113
+ if gapHasComment(src, prevStatementEnd(src, ws), start) {
114
+ return
115
+ }
116
+ edits = append(edits, TextEdit{
117
+ Pos: ws,
118
+ End: start,
119
+ Text: layout.eol + layout.indent(depth),
120
+ })
121
+ })
122
+ if len(edits) == 0 {
123
+ return
124
+ }
125
+ ctx.ReportRangeFix(
126
+ edits[0].Pos,
127
+ edits[0].End,
128
+ "Each statement must begin on its own line.",
129
+ edits...,
130
+ )
131
+ }
132
+
133
+ // gapHasComment reports whether the byte range [start, end) contains the
134
+ // opening bytes of a `//` or `/*` comment. The split rule abstains when
135
+ // the inter-statement gap carries a comment so its line-break insertion
136
+ // never deletes the comment.
137
+ func gapHasComment(src string, start, end int) bool {
138
+ if start < 0 {
139
+ start = 0
140
+ }
141
+ for i := start; i+1 < end && i+1 < len(src); i++ {
142
+ if src[i] == '/' && (src[i+1] == '/' || src[i+1] == '*') {
143
+ return true
144
+ }
145
+ }
146
+ return false
147
+ }
148
+
149
+ // prevStatementEnd returns the offset where the content preceding `stmt`
150
+ // on its line ends, used as the lower bound of the inter-statement gap
151
+ // scanned for comments. It locates `stmt` in its parent statement list
152
+ // and returns the previous sibling's end; for the first statement of a
153
+ // list it returns the parent owner's start (the `{`/`case:` boundary).
154
+ // The fallback walks back from `floor` to the previous non-whitespace
155
+ // byte so a comment-free caller still gets a sane lower bound.
156
+ func prevStatementEnd(src string, floor int) int {
157
+ // floor sits just past the whitespace run before the statement, i.e.
158
+ // immediately after the previous content's last byte. Walking back one
159
+ // byte lands inside that content; the gap to scan is everything from
160
+ // the start of the current line up to floor, but a comment belongs to
161
+ // this gap only when it follows the previous statement's terminator on
162
+ // the same line. Scanning from the line start would also catch a
163
+ // comment that belongs to an earlier statement, so bound the scan at
164
+ // the nearest preceding statement terminator (`;`, `}`) or label
165
+ // (`:`), or the line start, whichever comes first.
166
+ i := floor - 1
167
+ for i >= 0 {
168
+ c := src[i]
169
+ if c == '\n' {
170
+ return i + 1
171
+ }
172
+ if c == ';' || c == '}' || c == '{' || c == ':' {
173
+ return i + 1
174
+ }
175
+ i--
176
+ }
177
+ return 0
178
+ }
179
+
180
+ // firstStatementAfterCaseLabel reports whether `stmt` is the first
181
+ // statement of a `case`/`default` clause. Such a statement follows only
182
+ // the clause label on its line, not a preceding statement, so the split
183
+ // rule must not break a block off its label (`case 2: {` stays intact).
184
+ func firstStatementAfterCaseLabel(stmt *shimast.Node) bool {
185
+ if stmt == nil || stmt.Parent == nil {
186
+ return false
187
+ }
188
+ parent := stmt.Parent
189
+ if parent.Kind != shimast.KindCaseClause && parent.Kind != shimast.KindDefaultClause {
190
+ return false
191
+ }
192
+ clause := parent.AsCaseOrDefaultClause()
193
+ if clause == nil || clause.Statements == nil || len(clause.Statements.Nodes) == 0 {
194
+ return false
195
+ }
196
+ return clause.Statements.Nodes[0] == stmt
197
+ }
198
+
199
+ // formatLayout is the resolved indentation + EOL snapshot the structural
200
+ // format rules share. Defaults match Prettier: 2-space indent, spaces
201
+ // (not tabs), LF newlines.
202
+ type formatLayout struct {
203
+ tabWidth int
204
+ useTabs bool
205
+ eol string
206
+ }
207
+
208
+ // indent returns the indentation string for `depth` nesting levels:
209
+ // `depth` tab characters when useTabs, otherwise `depth * tabWidth`
210
+ // spaces.
211
+ func (l formatLayout) indent(depth int) string {
212
+ if depth <= 0 {
213
+ return ""
214
+ }
215
+ if l.useTabs {
216
+ return strings.Repeat("\t", depth)
217
+ }
218
+ return strings.Repeat(" ", depth*l.tabWidth)
219
+ }
220
+
221
+ // loadFormatLayout decodes the shared tabWidth/useTabs/endOfLine options
222
+ // used by `format/statement-split` and `format/indent` and applies the
223
+ // Prettier defaults. Both rules carry the identical option struct shape,
224
+ // so the decode is funneled through the statement-split option struct.
225
+ func loadFormatLayout(ctx *Context) formatLayout {
226
+ var opts formatStatementSplitOptions
227
+ _ = ctx.DecodeOptions(&opts)
228
+ layout := formatLayout{tabWidth: 2, useTabs: false, eol: "\n"}
229
+ if opts.TabWidth != nil && *opts.TabWidth > 0 {
230
+ layout.tabWidth = *opts.TabWidth
231
+ }
232
+ if opts.UseTabs != nil {
233
+ layout.useTabs = *opts.UseTabs
234
+ }
235
+ if opts.EndOfLine != nil && *opts.EndOfLine == "crlf" {
236
+ layout.eol = "\r\n"
237
+ }
238
+ return layout
239
+ }
240
+
241
+ // forEachStatementInList walks the file's AST and invokes `fn` once for
242
+ // every statement that lives directly inside a statement list, the
243
+ // SourceFile body, a Block, a ModuleBlock, or a case/default clause.
244
+ // `depth` is the nesting level used to compute indentation: one level
245
+ // per enclosing Block or ModuleBlock plus one per enclosing case/default
246
+ // clause. Top-level statements are depth 0.
247
+ //
248
+ // The SourceFile body's statements are visited at depth 0, then the walk
249
+ // recurses through the whole subtree via `ForEachChild`, bumping the
250
+ // depth on each statement-list owner it descends into. The rule's
251
+ // KindSourceFile registration therefore sees every nested statement
252
+ // without the engine dispatching one node kind at a time.
253
+ func forEachStatementInList(file *shimast.SourceFile, fn func(stmt *shimast.Node, depth int)) {
254
+ if file == nil || file.Statements == nil {
255
+ return
256
+ }
257
+ for _, stmt := range file.Statements.Nodes {
258
+ if stmt == nil {
259
+ continue
260
+ }
261
+ fn(stmt, 0)
262
+ }
263
+ walkStatementLists(file.AsNode(), file.Text(), 0, fn)
264
+ }
265
+
266
+ // blockStartsOwnLine reports whether a brace block opens on its own line, the
267
+ // `{` being the first non-whitespace byte of its physical line. A case/default
268
+ // body block written as `case X: {` shares the label's line (false); one
269
+ // written as `case X:` then `{` on the next line starts its own line (true).
270
+ // Prettier indents the former like a braceless `case X: stmt` (no extra level)
271
+ // but the latter like an ordinary nested block (one level deeper).
272
+ func blockStartsOwnLine(src string, block *shimast.Node) bool {
273
+ if block == nil {
274
+ return false
275
+ }
276
+ pos := shimscanner.SkipTrivia(src, block.Pos())
277
+ if pos < 0 || pos > len(src) {
278
+ return false
279
+ }
280
+ lineStart := lineStartOffset(src, pos)
281
+ for i := lineStart; i < pos; i++ {
282
+ if src[i] != ' ' && src[i] != '\t' {
283
+ return false
284
+ }
285
+ }
286
+ return true
287
+ }
288
+
289
+ // walkStatementLists recurses through `node`'s children. When it
290
+ // descends into a statement-list owner (Block, ModuleBlock, case/default
291
+ // clause) it bumps `depth` and invokes `fn` for each statement that
292
+ // owner directly holds, so a statement is always reported at the depth
293
+ // of the list it belongs to. The SourceFile body is visited by the
294
+ // caller, so this function only handles the nested owners.
295
+ //
296
+ // Some nodes are descend-only +1 frames: they are not statement lists
297
+ // themselves but their child statement lists nest one column deeper than
298
+ // the node. Two cases need this:
299
+ //
300
+ // - KindCaseBlock wraps a switch's clauses
301
+ // (SwitchStatement -> CaseBlock -> CaseClause -> statements). The
302
+ // braces sit one level under `switch`, and the clause body sits one
303
+ // level under `case:`, so a case-body statement is switchDepth+2.
304
+ // The clause's own +1 stacks on top of the CaseBlock's +1.
305
+ // - A class/interface/object-type-literal/object-literal body is not a
306
+ // statement list, but a member's method/constructor Block nests
307
+ // inside it. Without counting the body frame a method-body statement
308
+ // would land one column short (the member Block's +1 only), so
309
+ // already-correct 4-space class bodies would be rewritten to 2.
310
+ func walkStatementLists(node *shimast.Node, src string, depth int, fn func(stmt *shimast.Node, depth int)) {
311
+ if node == nil {
312
+ return
313
+ }
314
+ node.ForEachChild(func(child *shimast.Node) bool {
315
+ if child == nil {
316
+ return false
317
+ }
318
+ childDepth := depth
319
+ switch child.Kind {
320
+ case shimast.KindBlock, shimast.KindModuleBlock:
321
+ childDepth = depth + 1
322
+ // A same-line `case X: { stmt }` block does not add an indent level:
323
+ // Prettier indents it exactly like a braceless `case X: stmt`, the
324
+ // clause having already contributed the level. A block written on its
325
+ // OWN line under the clause (`case X:` then `{` on the next line) is an
326
+ // ordinary nested block and keeps its extra level, so only collapse the
327
+ // same-line form.
328
+ if child.Kind == shimast.KindBlock && child.Parent != nil &&
329
+ (child.Parent.Kind == shimast.KindCaseClause ||
330
+ child.Parent.Kind == shimast.KindDefaultClause) &&
331
+ !blockStartsOwnLine(src, child) {
332
+ childDepth = depth
333
+ }
334
+ for _, stmt := range child.Statements() {
335
+ if stmt == nil {
336
+ continue
337
+ }
338
+ fn(stmt, childDepth)
339
+ }
340
+ case shimast.KindCaseClause, shimast.KindDefaultClause:
341
+ childDepth = depth + 1
342
+ clause := child.AsCaseOrDefaultClause()
343
+ if clause != nil && clause.Statements != nil {
344
+ for _, stmt := range clause.Statements.Nodes {
345
+ if stmt == nil {
346
+ continue
347
+ }
348
+ fn(stmt, childDepth)
349
+ }
350
+ }
351
+ case shimast.KindCaseBlock,
352
+ shimast.KindClassDeclaration,
353
+ shimast.KindClassExpression,
354
+ shimast.KindInterfaceDeclaration,
355
+ shimast.KindTypeLiteral,
356
+ shimast.KindObjectLiteralExpression:
357
+ // Descend-only +1 frame: not a visited statement list, but its
358
+ // nested statement lists sit one column deeper.
359
+ childDepth = depth + 1
360
+ }
361
+ walkStatementLists(child, src, childDepth, fn)
362
+ return false
363
+ })
364
+ }
365
+
366
+ func init() {
367
+ Register(formatStatementSplit{})
368
+ }
@@ -0,0 +1,77 @@
1
+ package linthost
2
+
3
+ import (
4
+ shimast "github.com/microsoft/typescript-go/shim/ast"
5
+ shimscanner "github.com/microsoft/typescript-go/shim/scanner"
6
+ )
7
+
8
+ // formatTernaryNullishParens parenthesizes a `??` expression used as the
9
+ // condition, consequent, or alternate of a conditional expression,
10
+ // matching Prettier 3. TypeScript permits an unparenthesized `??` in
11
+ // those positions (unlike `??` mixed with `||`/`&&`), but Prettier 3
12
+ // always adds the parens for clarity:
13
+ //
14
+ // cond ? a ?? b : c -> cond ? (a ?? b) : c
15
+ // a ?? b ? c : d -> (a ?? b) ? c : d
16
+ //
17
+ // Only `??` is wrapped; `||` and `&&` operands are left bare. The wrap is
18
+ // width-independent (it applies even when the ternary fits on one line),
19
+ // so it is a normalization rule rather than part of the print-width
20
+ // reflow. Idempotent: a wrapped operand parses as a parenthesized
21
+ // expression, not a bare `??`, so the next pass leaves it alone.
22
+ type formatTernaryNullishParens struct{}
23
+
24
+ func (formatTernaryNullishParens) Name() string { return "format/ternary-nullish-parens" }
25
+ func (formatTernaryNullishParens) IsFormat() bool { return true }
26
+
27
+ func (formatTernaryNullishParens) Visits() []shimast.Kind {
28
+ return []shimast.Kind{shimast.KindConditionalExpression}
29
+ }
30
+
31
+ func (formatTernaryNullishParens) Check(ctx *Context, node *shimast.Node) {
32
+ if ctx == nil || ctx.File == nil || node == nil {
33
+ return
34
+ }
35
+ cond := node.AsConditionalExpression()
36
+ if cond == nil {
37
+ return
38
+ }
39
+ src := ctx.File.Text()
40
+ var edits []TextEdit
41
+ for _, operand := range []*shimast.Node{cond.Condition, cond.WhenTrue, cond.WhenFalse} {
42
+ if !isBareNullishCoalescing(operand) {
43
+ continue
44
+ }
45
+ start := shimscanner.SkipTrivia(src, operand.Pos())
46
+ end := operand.End()
47
+ if start < 0 || end < start || end > len(src) {
48
+ continue
49
+ }
50
+ edits = append(edits, TextEdit{Pos: start, End: end, Text: "(" + src[start:end] + ")"})
51
+ }
52
+ if len(edits) == 0 {
53
+ return
54
+ }
55
+ ctx.ReportRangeFix(
56
+ edits[0].Pos,
57
+ edits[0].End,
58
+ "Parenthesize a nullish-coalescing operand of a conditional expression.",
59
+ edits...,
60
+ )
61
+ }
62
+
63
+ // isBareNullishCoalescing reports whether `node` is an unparenthesized
64
+ // `a ?? b` binary expression.
65
+ func isBareNullishCoalescing(node *shimast.Node) bool {
66
+ if node == nil || node.Kind != shimast.KindBinaryExpression {
67
+ return false
68
+ }
69
+ bin := node.AsBinaryExpression()
70
+ return bin != nil &&
71
+ bin.OperatorToken != nil &&
72
+ bin.OperatorToken.Kind == shimast.KindQuestionQuestionToken
73
+ }
74
+
75
+ func init() {
76
+ Register(formatTernaryNullishParens{})
77
+ }
@@ -5,7 +5,7 @@ import (
5
5
  )
6
6
 
7
7
  // formatTrailingComma adds trailing commas to multi-line lists. Mirrors
8
- // prettier's `trailingComma: "all"` default *not* a tunable.
8
+ // prettier's `trailingComma: "all"` default, *not* a tunable.
9
9
  //
10
10
  // Scope (intentionally narrower than the closing-brace surface of TS):
11
11
  //
@@ -109,6 +109,14 @@ func (formatTrailingComma) Check(ctx *Context, node *shimast.Node) {
109
109
  if call == nil {
110
110
  return
111
111
  }
112
+ if isDynamicImportCall(call) {
113
+ // Prettier never emits a trailing comma inside a dynamic
114
+ // `import(...)` argument list, even under trailingComma:"all", a
115
+ // documented exception because the import() spec historically
116
+ // rejected one. The printer half (print_nodes_call.go) honors the
117
+ // same exception so the two rules agree on the reflowed shape.
118
+ return
119
+ }
112
120
  considerTrailingComma(ctx, call.Arguments, node.End()-1)
113
121
  case shimast.KindNewExpression:
114
122
  if mode == "es5" {
@@ -268,12 +276,23 @@ func (formatTrailingComma) Check(ctx *Context, node *shimast.Node) {
268
276
  }
269
277
  }
270
278
 
279
+ // isDynamicImportCall reports whether a CallExpression is a dynamic
280
+ // `import(...)`: its callee is the `import` keyword itself, mirroring
281
+ // typescript-go's ast.IsImportCall. Prettier never emits a trailing
282
+ // comma inside a dynamic-import argument list, even under
283
+ // trailingComma:"all".
284
+ func isDynamicImportCall(call *shimast.CallExpression) bool {
285
+ return call != nil &&
286
+ call.Expression != nil &&
287
+ call.Expression.Kind == shimast.KindImportKeyword
288
+ }
289
+
271
290
  // considerTrailingComma reports a fix when the bracket-delimited list is
272
291
  // multi-line and missing its trailing comma. `closeBracketPos` points at
273
292
  // the closing punctuation byte itself (e.g. the `]` of an array literal).
274
293
  //
275
294
  // "Multi-line" means the close bracket sits on a different line from the
276
- // last element's end not just "the list contains a newline somewhere".
295
+ // last element's end, not just "the list contains a newline somewhere".
277
296
  // Prettier's `trailingComma: "all"` omits the comma whenever the close
278
297
  // bracket is adjacent to the last element on the same line, even if the
279
298
  // element itself is internally multi-line. The canonical shape is