@ttsc/lint 0.14.0-dev.20260529.2 → 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.
- package/README.md +21 -23
- package/lib/defaultFormat.d.ts +10 -6
- package/lib/defaultFormat.js +10 -6
- package/lib/defaultFormat.js.map +1 -1
- package/lib/structures/ITtscLintConfig.d.ts +5 -5
- package/lib/structures/TtscLintRuleSetting.d.ts +19 -19
- package/lib/structures/{ITtscLintFormat.d.ts → format/ITtscLintFormat.d.ts} +45 -70
- package/lib/structures/format/ITtscLintFormat.js.map +1 -0
- package/lib/structures/format/ITtscLintFormatJsDoc.d.ts +15 -0
- package/lib/structures/format/ITtscLintFormatJsDoc.js +3 -0
- package/lib/structures/format/ITtscLintFormatJsDoc.js.map +1 -0
- package/lib/structures/format/ITtscLintFormatSortImports.d.ts +54 -0
- package/lib/structures/format/ITtscLintFormatSortImports.js +3 -0
- package/lib/structures/format/ITtscLintFormatSortImports.js.map +1 -0
- package/lib/structures/format/index.d.ts +3 -0
- package/lib/structures/format/index.js +20 -0
- package/lib/structures/format/index.js.map +1 -0
- package/lib/structures/index.d.ts +1 -1
- package/lib/structures/index.js +1 -1
- package/lib/structures/index.js.map +1 -1
- package/lib/structures/rules/ITtscLintBoundariesRuleOptions.d.ts +18 -27
- package/lib/structures/rules/ITtscLintBoundariesRuleOptions.js +4 -5
- package/lib/structures/rules/ITtscLintBoundariesRuleOptions.js.map +1 -1
- package/lib/structures/rules/ITtscLintBoundariesRules.d.ts +29 -33
- package/lib/structures/rules/ITtscLintContributorRules.d.ts +6 -7
- package/lib/structures/rules/ITtscLintCoreRules.d.ts +380 -408
- package/lib/structures/rules/ITtscLintCypressRuleOptions.d.ts +5 -5
- package/lib/structures/rules/ITtscLintCypressRuleOptions.js +2 -2
- package/lib/structures/rules/ITtscLintCypressRules.d.ts +34 -38
- package/lib/structures/rules/ITtscLintFunctionalRuleOptions.d.ts +21 -24
- package/lib/structures/rules/ITtscLintFunctionalRuleOptions.js +2 -2
- package/lib/structures/rules/ITtscLintFunctionalRules.d.ts +51 -56
- package/lib/structures/rules/ITtscLintJestRules.d.ts +63 -74
- package/lib/structures/rules/ITtscLintJsdocRules.d.ts +47 -54
- package/lib/structures/rules/ITtscLintJsxA11yRules.d.ts +94 -102
- package/lib/structures/rules/ITtscLintNextjsRules.d.ts +50 -55
- package/lib/structures/rules/ITtscLintPlaywrightRules.d.ts +104 -122
- package/lib/structures/rules/ITtscLintPromiseRules.d.ts +62 -71
- package/lib/structures/rules/ITtscLintReactPerfRuleOptions.d.ts +4 -4
- package/lib/structures/rules/ITtscLintReactPerfRules.d.ts +17 -19
- package/lib/structures/rules/ITtscLintReactRuleOptions.d.ts +8 -10
- package/lib/structures/rules/ITtscLintReactRuleOptions.js +1 -2
- package/lib/structures/rules/ITtscLintReactRuleOptions.js.map +1 -1
- package/lib/structures/rules/ITtscLintReactRules.d.ts +91 -104
- package/lib/structures/rules/ITtscLintRegexpRules.d.ts +46 -54
- package/lib/structures/rules/ITtscLintRuleOptionsMap.d.ts +7 -8
- package/lib/structures/rules/ITtscLintSecurityRules.d.ts +45 -52
- package/lib/structures/rules/ITtscLintSolidRules.d.ts +53 -56
- package/lib/structures/rules/ITtscLintStorybookRuleOptions.d.ts +3 -4
- package/lib/structures/rules/ITtscLintStorybookRules.d.ts +60 -69
- package/lib/structures/rules/ITtscLintTanstackQueryRules.d.ts +31 -37
- package/lib/structures/rules/ITtscLintTestingLibraryRuleOptions.d.ts +2 -3
- package/lib/structures/rules/ITtscLintTestingLibraryRules.d.ts +102 -119
- package/lib/structures/rules/ITtscLintTypeScriptRules.d.ts +460 -518
- package/lib/structures/rules/ITtscLintVitestRules.d.ts +43 -51
- package/linthost/config.go +89 -72
- package/linthost/config_format.go +265 -99
- package/linthost/directives.go +5 -1
- package/linthost/display_width.go +72 -0
- package/linthost/fix.go +26 -1
- package/linthost/format.go +222 -25
- package/linthost/format_editor_settings.go +262 -0
- package/linthost/lsp.go +8 -4
- package/linthost/print_dispatch.go +3 -0
- package/linthost/print_doc.go +13 -0
- package/linthost/print_engine.go +68 -11
- package/linthost/print_nodes_array.go +108 -5
- package/linthost/print_nodes_call.go +515 -74
- package/linthost/print_nodes_function.go +25 -0
- package/linthost/print_nodes_imports.go +47 -14
- package/linthost/print_nodes_list.go +191 -8
- package/linthost/print_nodes_object.go +12 -6
- package/linthost/print_nodes_ternary.go +106 -0
- package/linthost/rules_boundaries.go +400 -400
- package/linthost/rules_camelcase.go +81 -81
- package/linthost/rules_complexity.go +52 -51
- package/linthost/rules_consistent_return.go +81 -81
- package/linthost/rules_core_extra.go +472 -472
- package/linthost/rules_curly.go +43 -43
- package/linthost/rules_default_case.go +15 -15
- package/linthost/rules_default_case_last.go +22 -22
- package/linthost/rules_format_arrow_parens.go +167 -0
- package/linthost/rules_format_bracket_spacing.go +117 -0
- package/linthost/rules_format_clause_join.go +172 -0
- package/linthost/rules_format_declaration_header.go +664 -0
- package/linthost/rules_format_indent.go +616 -0
- package/linthost/rules_format_jsdoc.go +4 -4
- package/linthost/rules_format_orphan_semi.go +106 -0
- package/linthost/rules_format_parameter_properties.go +175 -0
- package/linthost/rules_format_print_width.go +185 -69
- package/linthost/rules_format_quote_props.go +169 -0
- package/linthost/rules_format_quotes.go +75 -29
- package/linthost/rules_format_semi.go +185 -10
- package/linthost/rules_format_sort_imports.go +456 -121
- package/linthost/rules_format_statement_split.go +368 -0
- package/linthost/rules_format_ternary_nullish_parens.go +77 -0
- package/linthost/rules_format_trailing_comma.go +21 -2
- package/linthost/rules_format_whitespace.go +336 -0
- package/linthost/rules_functional.go +688 -688
- package/linthost/rules_gap.go +146 -11
- package/linthost/rules_grouped_accessor_pairs.go +60 -60
- package/linthost/rules_guard_for_in.go +122 -122
- package/linthost/rules_id_length.go +44 -44
- package/linthost/rules_imports.go +11 -3
- package/linthost/rules_init_declarations.go +25 -25
- package/linthost/rules_jsx_a11y.go +844 -844
- package/linthost/rules_max_classes_per_file.go +24 -24
- package/linthost/rules_max_depth.go +43 -43
- package/linthost/rules_max_lines.go +53 -53
- package/linthost/rules_max_lines_per_function.go +28 -28
- package/linthost/rules_max_nested_callbacks.go +26 -26
- package/linthost/rules_max_params.go +20 -20
- package/linthost/rules_max_statements.go +29 -29
- package/linthost/rules_nextjs.go +5 -5
- package/linthost/rules_no_else_return.go +38 -38
- package/linthost/rules_no_empty_named_blocks.go +45 -45
- package/linthost/rules_no_import_assign.go +96 -96
- package/linthost/rules_no_invalid_this.go +19 -19
- package/linthost/rules_no_loop_func.go +43 -43
- package/linthost/rules_no_magic_numbers.go +60 -60
- package/linthost/rules_no_mixed_operators.go +44 -44
- package/linthost/rules_no_param_reassign.go +64 -64
- package/linthost/rules_no_restricted_imports.go +45 -45
- package/linthost/rules_no_restricted_syntax.go +17 -17
- package/linthost/rules_no_shadow.go +112 -112
- package/linthost/rules_no_unreachable.go +36 -36
- package/linthost/rules_no_useless_assignment.go +79 -79
- package/linthost/rules_no_useless_constructor.go +167 -167
- package/linthost/rules_no_useless_return.go +28 -28
- package/linthost/rules_prefer_arrow_callback.go +74 -74
- package/linthost/rules_prefer_destructuring.go +61 -61
- package/linthost/rules_prefer_named_capture_group.go +87 -87
- package/linthost/rules_prefer_rest_params.go +61 -61
- package/linthost/rules_promise.go +800 -800
- package/linthost/rules_react.go +600 -600
- package/linthost/rules_react_extras.go +162 -162
- package/linthost/rules_react_hooks.go +2 -2
- package/linthost/rules_react_perf.go +231 -231
- package/linthost/rules_regexp.go +293 -293
- package/linthost/rules_security.go +613 -613
- package/linthost/rules_sort_imports.go +37 -37
- package/linthost/rules_sort_keys.go +88 -88
- package/linthost/rules_suggestions.go +13 -0
- package/linthost/rules_ts.go +2 -2
- package/linthost/rules_ts_async.go +247 -247
- package/linthost/rules_ts_class_literal_property_style.go +64 -64
- package/linthost/rules_ts_consistent_type_exports.go +209 -209
- package/linthost/rules_ts_explicit_function_return_type.go +35 -35
- package/linthost/rules_ts_extra.go +6 -2
- package/linthost/rules_ts_no_base_to_string.go +140 -140
- package/linthost/rules_ts_no_confusing_void.go +28 -28
- package/linthost/rules_ts_no_deprecated.go +110 -110
- package/linthost/rules_ts_no_for_in_array.go +45 -45
- package/linthost/rules_ts_no_magic_numbers.go +67 -67
- package/linthost/rules_ts_no_meaningless_void_operator.go +44 -44
- package/linthost/rules_ts_no_misused_spread.go +64 -64
- package/linthost/rules_ts_no_redundant_type_constituents.go +72 -72
- package/linthost/rules_ts_no_restricted_types.go +28 -28
- package/linthost/rules_ts_no_unnecessary_boolean_literal_compare.go +87 -87
- package/linthost/rules_ts_no_unnecessary_condition.go +184 -184
- package/linthost/rules_ts_no_unnecessary_qualifier.go +72 -72
- package/linthost/rules_ts_no_unnecessary_template_expression.go +120 -120
- package/linthost/rules_ts_no_unnecessary_type_arguments.go +171 -171
- package/linthost/rules_ts_no_unnecessary_type_assertion.go +90 -90
- package/linthost/rules_ts_no_unsafe_argument.go +50 -50
- package/linthost/rules_ts_no_unsafe_assignment.go +60 -60
- package/linthost/rules_ts_no_unsafe_call.go +40 -40
- package/linthost/rules_ts_no_unsafe_enum_comparison.go +147 -147
- package/linthost/rules_ts_no_unsafe_member_access.go +29 -29
- package/linthost/rules_ts_no_unsafe_return.go +64 -64
- package/linthost/rules_ts_no_unsafe_unary_minus.go +42 -42
- package/linthost/rules_ts_no_useless_constructor.go +20 -20
- package/linthost/rules_ts_non_nullable_type_assertion_style.go +60 -60
- package/linthost/rules_ts_parameter_properties.go +10 -10
- package/linthost/rules_ts_prefer_find.go +116 -116
- package/linthost/rules_ts_prefer_includes.go +173 -173
- package/linthost/rules_ts_prefer_nullish_coalescing.go +54 -54
- package/linthost/rules_ts_prefer_optional_chain.go +156 -156
- package/linthost/rules_ts_prefer_promise_reject_errors.go +104 -104
- package/linthost/rules_ts_prefer_readonly.go +31 -31
- package/linthost/rules_ts_prefer_reduce_type_parameter.go +74 -74
- package/linthost/rules_ts_prefer_regexp_exec.go +69 -69
- package/linthost/rules_ts_prefer_return_this_type.go +79 -79
- package/linthost/rules_ts_prefer_string_starts_ends_with.go +237 -237
- package/linthost/rules_ts_promise_function_async.go +41 -41
- package/linthost/rules_ts_related_getter_setter_pairs.go +61 -61
- package/linthost/rules_ts_require_array_sort_compare.go +58 -58
- package/linthost/rules_ts_restrict_plus_operands.go +82 -82
- package/linthost/rules_ts_restrict_template_expressions.go +50 -50
- package/linthost/rules_ts_simple.go +249 -249
- package/linthost/rules_ts_sort_type_constituents.go +88 -88
- package/linthost/rules_ts_strict_boolean_expressions.go +103 -103
- package/linthost/rules_ts_switch_exhaustiveness_check.go +90 -90
- package/linthost/rules_ts_unbound_method.go +65 -65
- package/linthost/rules_tsdoc.go +88 -88
- package/linthost/rules_unicorn_better_regex.go +1 -1
- package/linthost/rules_unicorn_catch_error_name.go +19 -19
- package/linthost/rules_unicorn_consistent_assert.go +20 -20
- package/linthost/rules_unicorn_consistent_date_clone.go +27 -27
- package/linthost/rules_unicorn_consistent_destructuring.go +3 -3
- package/linthost/rules_unicorn_consistent_empty_array_spread.go +34 -34
- package/linthost/rules_unicorn_consistent_existence_index_check.go +42 -42
- package/linthost/rules_unicorn_consistent_function_scoping.go +3 -3
- package/linthost/rules_unicorn_consistent_template_literal_escape.go +3 -3
- package/linthost/rules_unicorn_custom_error_definition.go +92 -92
- package/linthost/rules_unicorn_empty_brace_spaces.go +47 -47
- package/linthost/rules_unicorn_error_message.go +34 -34
- package/linthost/rules_unicorn_escape_case.go +14 -14
- package/linthost/rules_unicorn_expiring_todo_comments.go +36 -36
- package/linthost/rules_unicorn_explicit_length_check.go +51 -51
- package/linthost/rules_unicorn_filename_case.go +1 -1
- package/linthost/rules_unicorn_import_style.go +1 -1
- package/linthost/rules_unicorn_isolated_functions.go +2 -2
- package/linthost/rules_unicorn_new_for_builtins.go +49 -49
- package/linthost/rules_unicorn_no_abusive_eslint_disable.go +31 -31
- package/linthost/rules_unicorn_no_accessor_recursion.go +69 -69
- package/linthost/rules_unicorn_no_anonymous_default_export.go +40 -40
- package/linthost/rules_unicorn_no_array_callback_reference.go +33 -33
- package/linthost/rules_unicorn_no_array_for_each.go +14 -14
- package/linthost/rules_unicorn_no_array_method_this_argument.go +29 -29
- package/linthost/rules_unicorn_no_array_reduce.go +15 -15
- package/linthost/rules_unicorn_no_array_reverse.go +17 -17
- package/linthost/rules_unicorn_no_array_sort.go +17 -17
- package/linthost/rules_unicorn_no_await_expression_member.go +12 -12
- package/linthost/rules_unicorn_no_await_in_promise_methods.go +38 -38
- package/linthost/rules_unicorn_no_console_spaces.go +30 -30
- package/linthost/rules_unicorn_no_document_cookie.go +13 -13
- package/linthost/rules_unicorn_no_empty_file.go +16 -16
- package/linthost/rules_unicorn_no_for_loop.go +58 -58
- package/linthost/rules_unicorn_no_hex_escape.go +11 -11
- package/linthost/rules_unicorn_no_immediate_mutation.go +55 -55
- package/linthost/rules_unicorn_no_instanceof_builtins.go +34 -34
- package/linthost/rules_unicorn_no_invalid_fetch_options.go +52 -52
- package/linthost/rules_unicorn_no_invalid_remove_event_listener.go +25 -25
- package/linthost/rules_unicorn_no_keyword_prefix.go +56 -56
- package/linthost/rules_unicorn_no_lonely_if.go +21 -21
- package/linthost/rules_unicorn_no_magic_array_flat_depth.go +22 -22
- package/linthost/rules_unicorn_no_named_default.go +25 -25
- package/linthost/rules_unicorn_no_negated_condition.go +54 -54
- package/linthost/rules_unicorn_no_negation_in_equality_check.go +23 -23
- package/linthost/rules_unicorn_no_nested_ternary.go +15 -15
- package/linthost/rules_unicorn_no_new_array.go +5 -5
- package/linthost/rules_unicorn_no_new_buffer.go +5 -5
- package/linthost/rules_unicorn_no_null.go +2 -2
- package/linthost/rules_unicorn_no_object_as_default_parameter.go +19 -19
- package/linthost/rules_unicorn_no_process_exit.go +17 -17
- package/linthost/rules_unicorn_no_single_promise_in_promise_methods.go +29 -29
- package/linthost/rules_unicorn_no_static_only_class.go +27 -27
- package/linthost/rules_unicorn_no_thenable.go +47 -47
- package/linthost/rules_unicorn_no_this_assignment.go +10 -10
- package/linthost/rules_unicorn_no_typeof_undefined.go +31 -31
- package/linthost/rules_unicorn_no_unnecessary_array_flat_depth.go +23 -23
- package/linthost/rules_unicorn_no_unnecessary_array_splice_count.go +37 -37
- package/linthost/rules_unicorn_no_unnecessary_await.go +24 -24
- package/linthost/rules_unicorn_no_unnecessary_slice_end.go +22 -22
- package/linthost/rules_unicorn_no_unreadable_array_destructuring.go +67 -67
- package/linthost/rules_unicorn_no_unreadable_iife.go +22 -22
- package/linthost/rules_unicorn_no_useless_collection_argument.go +34 -34
- package/linthost/rules_unicorn_no_useless_error_capture_stack_trace.go +18 -18
- package/linthost/rules_unicorn_no_useless_fallback_in_spread.go +49 -49
- package/linthost/rules_unicorn_no_useless_iterator_to_array.go +41 -41
- package/linthost/rules_unicorn_no_useless_length_check.go +82 -82
- package/linthost/rules_unicorn_no_useless_promise_resolve_reject.go +42 -42
- package/linthost/rules_unicorn_no_useless_spread.go +38 -38
- package/linthost/rules_unicorn_no_useless_switch_case.go +29 -29
- package/linthost/rules_unicorn_no_useless_undefined.go +25 -25
- package/linthost/rules_unicorn_no_zero_fractions.go +17 -17
- package/linthost/rules_unicorn_number_literal_case.go +33 -33
- package/linthost/rules_unicorn_numeric_separators_style.go +36 -36
- package/linthost/rules_unicorn_prefer_add_event_listener.go +30 -30
- package/linthost/rules_unicorn_prefer_array_find.go +27 -27
- package/linthost/rules_unicorn_prefer_array_flat.go +25 -25
- package/linthost/rules_unicorn_prefer_array_flat_map.go +37 -37
- package/linthost/rules_unicorn_prefer_array_index_of.go +108 -108
- package/linthost/rules_unicorn_prefer_array_some.go +43 -43
- package/linthost/rules_unicorn_prefer_at.go +42 -42
- package/linthost/rules_unicorn_prefer_bigint_literals.go +42 -42
- package/linthost/rules_unicorn_prefer_blob_reading_methods.go +15 -15
- package/linthost/rules_unicorn_prefer_class_fields.go +57 -57
- package/linthost/rules_unicorn_prefer_classlist_toggle.go +76 -76
- package/linthost/rules_unicorn_prefer_code_point.go +21 -21
- package/linthost/rules_unicorn_prefer_date_now.go +47 -47
- package/linthost/rules_unicorn_prefer_default_parameters.go +96 -96
- package/linthost/rules_unicorn_prefer_dom_node_append.go +14 -14
- package/linthost/rules_unicorn_prefer_dom_node_dataset.go +27 -27
- package/linthost/rules_unicorn_prefer_dom_node_remove.go +17 -17
- package/linthost/rules_unicorn_prefer_dom_node_text_content.go +11 -11
- package/linthost/rules_unicorn_prefer_event_target.go +10 -10
- package/linthost/rules_unicorn_prefer_export_from.go +99 -99
- package/linthost/rules_unicorn_prefer_global_this.go +91 -91
- package/linthost/rules_unicorn_prefer_import_meta_properties.go +38 -38
- package/linthost/rules_unicorn_prefer_includes.go +108 -108
- package/linthost/rules_unicorn_prefer_json_parse_buffer.go +37 -37
- package/linthost/rules_unicorn_prefer_keyboard_event_key.go +10 -10
- package/linthost/rules_unicorn_prefer_logical_operator_over_ternary.go +20 -20
- package/linthost/rules_unicorn_prefer_math_min_max.go +33 -33
- package/linthost/rules_unicorn_prefer_math_trunc.go +32 -32
- package/linthost/rules_unicorn_prefer_modern_dom_apis.go +18 -18
- package/linthost/rules_unicorn_prefer_modern_math_apis.go +38 -38
- package/linthost/rules_unicorn_prefer_module.go +22 -22
- package/linthost/rules_unicorn_prefer_native_coercion_functions.go +73 -73
- package/linthost/rules_unicorn_prefer_negative_index.go +46 -46
- package/linthost/rules_unicorn_prefer_node_protocol.go +90 -90
- package/linthost/rules_unicorn_prefer_number_properties.go +57 -57
- package/linthost/rules_unicorn_prefer_object_from_entries.go +26 -26
- package/linthost/rules_unicorn_prefer_optional_catch_binding.go +24 -24
- package/linthost/rules_unicorn_prefer_prototype_methods.go +25 -25
- package/linthost/rules_unicorn_prefer_query_selector.go +25 -25
- package/linthost/rules_unicorn_prefer_reflect_apply.go +10 -10
- package/linthost/rules_unicorn_prefer_regexp_test_rule.go +47 -47
- package/linthost/rules_unicorn_prefer_response_static_json.go +26 -26
- package/linthost/rules_unicorn_prefer_set_has.go +16 -16
- package/linthost/rules_unicorn_prefer_set_size.go +22 -22
- package/linthost/rules_unicorn_prefer_simple_condition_first.go +3 -3
- package/linthost/rules_unicorn_prefer_single_call.go +59 -59
- package/linthost/rules_unicorn_prefer_spread.go +24 -24
- package/linthost/rules_unicorn_prefer_string_raw.go +12 -12
- package/linthost/rules_unicorn_prefer_string_replace_all.go +46 -46
- package/linthost/rules_unicorn_prefer_string_slice.go +17 -17
- package/linthost/rules_unicorn_prefer_string_starts_ends_with.go +104 -104
- package/linthost/rules_unicorn_prefer_string_trim_start_end.go +21 -21
- package/linthost/rules_unicorn_prefer_structured_clone.go +36 -36
- package/linthost/rules_unicorn_prefer_switch.go +65 -65
- package/linthost/rules_unicorn_prefer_ternary.go +35 -35
- package/linthost/rules_unicorn_prefer_top_level_await.go +34 -34
- package/linthost/rules_unicorn_prefer_type_error.go +84 -84
- package/linthost/rules_unicorn_prevent_abbreviations.go +68 -68
- package/linthost/rules_unicorn_relative_url_style.go +19 -19
- package/linthost/rules_unicorn_require_array_join_separator.go +18 -18
- package/linthost/rules_unicorn_require_module_attributes.go +25 -25
- package/linthost/rules_unicorn_require_module_specifiers.go +28 -28
- package/linthost/rules_unicorn_require_number_to_fixed_digits_argument.go +18 -18
- package/linthost/rules_unicorn_require_post_message_target_origin.go +18 -18
- package/linthost/rules_unicorn_string_content.go +1 -1
- package/linthost/rules_unicorn_switch_case_braces.go +16 -16
- package/linthost/rules_unicorn_switch_case_break_position.go +3 -3
- package/linthost/rules_unicorn_template_indent.go +1 -1
- package/linthost/rules_unicorn_text_encoding_identifier_case.go +36 -36
- package/linthost/rules_unicorn_throw_new_error.go +30 -30
- package/linthost/rules_var.go +273 -3
- package/package.json +3 -3
- package/src/defaultFormat.ts +11 -7
- package/src/structures/ITtscLintConfig.ts +5 -5
- package/src/structures/TtscLintRuleSetting.ts +19 -19
- package/src/structures/{ITtscLintFormat.ts → format/ITtscLintFormat.ts} +48 -75
- package/src/structures/format/ITtscLintFormatJsDoc.ts +16 -0
- package/src/structures/format/ITtscLintFormatSortImports.ts +62 -0
- package/src/structures/format/index.ts +3 -0
- package/src/structures/index.ts +1 -1
- package/src/structures/rules/ITtscLintBoundariesRuleOptions.ts +20 -31
- package/src/structures/rules/ITtscLintBoundariesRules.ts +32 -36
- package/src/structures/rules/ITtscLintContributorRules.ts +6 -7
- package/src/structures/rules/ITtscLintCoreRules.ts +380 -408
- package/src/structures/rules/ITtscLintCypressRuleOptions.ts +5 -5
- package/src/structures/rules/ITtscLintCypressRules.ts +34 -38
- package/src/structures/rules/ITtscLintFunctionalRuleOptions.ts +28 -41
- package/src/structures/rules/ITtscLintFunctionalRules.ts +51 -56
- package/src/structures/rules/ITtscLintJestRules.ts +63 -74
- package/src/structures/rules/ITtscLintJsdocRules.ts +47 -54
- package/src/structures/rules/ITtscLintJsxA11yRules.ts +94 -102
- package/src/structures/rules/ITtscLintNextjsRules.ts +50 -55
- package/src/structures/rules/ITtscLintPlaywrightRules.ts +104 -122
- package/src/structures/rules/ITtscLintPromiseRules.ts +62 -71
- package/src/structures/rules/ITtscLintReactPerfRuleOptions.ts +4 -4
- package/src/structures/rules/ITtscLintReactPerfRules.ts +17 -19
- package/src/structures/rules/ITtscLintReactRuleOptions.ts +8 -10
- package/src/structures/rules/ITtscLintReactRules.ts +91 -104
- package/src/structures/rules/ITtscLintRegexpRules.ts +46 -54
- package/src/structures/rules/ITtscLintRuleOptionsMap.ts +7 -8
- package/src/structures/rules/ITtscLintSecurityRules.ts +45 -52
- package/src/structures/rules/ITtscLintSolidRules.ts +53 -56
- package/src/structures/rules/ITtscLintStorybookRuleOptions.ts +3 -4
- package/src/structures/rules/ITtscLintStorybookRules.ts +60 -69
- package/src/structures/rules/ITtscLintTanstackQueryRules.ts +31 -37
- package/src/structures/rules/ITtscLintTestingLibraryRuleOptions.ts +2 -3
- package/src/structures/rules/ITtscLintTestingLibraryRules.ts +102 -119
- package/src/structures/rules/ITtscLintTypeScriptRules.ts +460 -518
- package/src/structures/rules/ITtscLintVitestRules.ts +43 -51
- package/lib/structures/ITtscLintFormat.js.map +0 -1
- /package/lib/structures/{ITtscLintFormat.js → format/ITtscLintFormat.js} +0 -0
|
@@ -2,60 +2,54 @@ import type { TtscLintRuleSetting } from "../TtscLintRuleSetting";
|
|
|
2
2
|
/**
|
|
3
3
|
* Vitest test source rules from `@vitest/eslint-plugin`.
|
|
4
4
|
*
|
|
5
|
-
* Vitest reuses much of Jest's testing surface but ships its own
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
5
|
+
* Vitest reuses much of Jest's testing surface but ships its own runner and
|
|
6
|
+
* configuration. These rules mirror the ergonomic subset of
|
|
7
|
+
* `eslint-plugin-jest` adapted for Vitest semantics — focused tests, identical
|
|
8
|
+
* titles, conditional logic, valid `expect` shape.
|
|
9
9
|
*
|
|
10
10
|
* @reference https://github.com/vitest-dev/eslint-plugin-vitest
|
|
11
11
|
*/
|
|
12
12
|
export interface ITtscLintVitestRules {
|
|
13
13
|
/**
|
|
14
|
-
* Require every Vitest test body to contain at least one
|
|
15
|
-
*
|
|
16
|
-
* giving a false-positive signal.
|
|
14
|
+
* Require every Vitest test body to contain at least one `expect(...)` call.
|
|
15
|
+
* A test with no assertions still passes, giving a false-positive signal.
|
|
17
16
|
*
|
|
18
17
|
* @reference https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/expect-expect.md
|
|
19
18
|
*/
|
|
20
19
|
"vitest/expect-expect"?: TtscLintRuleSetting;
|
|
21
20
|
/**
|
|
22
|
-
* Reject `expect(...)` calls under `if`/`try`/`catch` or other
|
|
23
|
-
*
|
|
21
|
+
* Reject `expect(...)` calls under `if`/`try`/`catch` or other conditional
|
|
22
|
+
* branches in Vitest tests.
|
|
24
23
|
*
|
|
25
|
-
* A branch that never runs turns the assertion into a silent no-op
|
|
26
|
-
*
|
|
24
|
+
* A branch that never runs turns the assertion into a silent no-op rather
|
|
25
|
+
* than a failure.
|
|
27
26
|
*
|
|
28
27
|
* @reference https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-conditional-expect.md
|
|
29
28
|
*/
|
|
30
29
|
"vitest/no-conditional-expect"?: TtscLintRuleSetting;
|
|
31
30
|
/**
|
|
32
|
-
* Reject `test(...)`/`it(...)` declarations inside loops or `if`
|
|
33
|
-
* branches.
|
|
31
|
+
* Reject `test(...)`/`it(...)` declarations inside loops or `if` branches.
|
|
34
32
|
*
|
|
35
|
-
* Vitest collects tests at module load, so a conditional
|
|
36
|
-
*
|
|
37
|
-
* appears to describe.
|
|
33
|
+
* Vitest collects tests at module load, so a conditional declaration produces
|
|
34
|
+
* a different suite shape than the file appears to describe.
|
|
38
35
|
*
|
|
39
36
|
* @reference https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-conditional-tests.md
|
|
40
37
|
*/
|
|
41
38
|
"vitest/no-conditional-tests"?: TtscLintRuleSetting;
|
|
42
39
|
/**
|
|
43
|
-
* Reject `test.skip`, `it.skip`, `describe.skip`, and `.todo`
|
|
44
|
-
* variants.
|
|
40
|
+
* Reject `test.skip`, `it.skip`, `describe.skip`, and `.todo` variants.
|
|
45
41
|
*
|
|
46
|
-
* Disabled tests rot in place and quietly drop coverage for the
|
|
47
|
-
*
|
|
42
|
+
* Disabled tests rot in place and quietly drop coverage for the feature they
|
|
43
|
+
* were meant to pin.
|
|
48
44
|
*
|
|
49
45
|
* @reference https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-disabled-tests.md
|
|
50
46
|
*/
|
|
51
47
|
"vitest/no-disabled-tests"?: TtscLintRuleSetting;
|
|
52
48
|
/**
|
|
53
|
-
* Reject `done` callback parameters in Vitest tests and
|
|
54
|
-
* lifecycle hooks.
|
|
49
|
+
* Reject `done` callback parameters in Vitest tests and lifecycle hooks.
|
|
55
50
|
*
|
|
56
|
-
* The callback style predates async/await and makes failure
|
|
57
|
-
*
|
|
58
|
-
* `async` instead.
|
|
51
|
+
* The callback style predates async/await and makes failure propagation easy
|
|
52
|
+
* to miss; return a Promise or mark the body `async` instead.
|
|
59
53
|
*
|
|
60
54
|
* @reference https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-done-callback.md
|
|
61
55
|
*/
|
|
@@ -63,18 +57,18 @@ export interface ITtscLintVitestRules {
|
|
|
63
57
|
/**
|
|
64
58
|
* Reject `test.only`, `it.only`, and `describe.only`.
|
|
65
59
|
*
|
|
66
|
-
* A focused suite silently skips the rest of the file, so a stray
|
|
67
|
-
*
|
|
60
|
+
* A focused suite silently skips the rest of the file, so a stray `.only`
|
|
61
|
+
* left from debugging hides every other test in CI.
|
|
68
62
|
*
|
|
69
63
|
* @reference https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-focused-tests.md
|
|
70
64
|
*/
|
|
71
65
|
"vitest/no-focused-tests"?: TtscLintRuleSetting;
|
|
72
66
|
/**
|
|
73
|
-
* Reject duplicate Vitest test or `describe` titles within the
|
|
74
|
-
*
|
|
67
|
+
* Reject duplicate Vitest test or `describe` titles within the same suite
|
|
68
|
+
* scope.
|
|
75
69
|
*
|
|
76
|
-
* The runner cannot disambiguate two siblings with identical names
|
|
77
|
-
*
|
|
70
|
+
* The runner cannot disambiguate two siblings with identical names in its
|
|
71
|
+
* error output or filter flags.
|
|
78
72
|
*
|
|
79
73
|
* @reference https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-identical-title.md
|
|
80
74
|
*/
|
|
@@ -82,28 +76,28 @@ export interface ITtscLintVitestRules {
|
|
|
82
76
|
/**
|
|
83
77
|
* Reject `expect(...)` calls outside Vitest tests and hooks.
|
|
84
78
|
*
|
|
85
|
-
* Top-level assertions execute at module load before any test
|
|
86
|
-
*
|
|
79
|
+
* Top-level assertions execute at module load before any test starts, so
|
|
80
|
+
* failures never attach to a named case.
|
|
87
81
|
*
|
|
88
82
|
* @reference https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-standalone-expect.md
|
|
89
83
|
*/
|
|
90
84
|
"vitest/no-standalone-expect"?: TtscLintRuleSetting;
|
|
91
85
|
/**
|
|
92
|
-
* Reject `return` statements that return non-Promise values from
|
|
93
|
-
*
|
|
86
|
+
* Reject `return` statements that return non-Promise values from a Vitest
|
|
87
|
+
* test callback.
|
|
94
88
|
*
|
|
95
|
-
* The runner ignores the value and following code is dead, which
|
|
96
|
-
*
|
|
89
|
+
* The runner ignores the value and following code is dead, which usually
|
|
90
|
+
* masks a missing `await` or stray early-exit.
|
|
97
91
|
*
|
|
98
92
|
* @reference https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-test-return-statement.md
|
|
99
93
|
*/
|
|
100
94
|
"vitest/no-test-return-statement"?: TtscLintRuleSetting;
|
|
101
95
|
/**
|
|
102
|
-
* Prefer `expect(value).toHaveLength(n)` over asserting on
|
|
103
|
-
*
|
|
96
|
+
* Prefer `expect(value).toHaveLength(n)` over asserting on `value.length`
|
|
97
|
+
* with `toBe`.
|
|
104
98
|
*
|
|
105
|
-
* The dedicated matcher reports the actual length on failure
|
|
106
|
-
*
|
|
99
|
+
* The dedicated matcher reports the actual length on failure instead of a
|
|
100
|
+
* bare number mismatch.
|
|
107
101
|
*
|
|
108
102
|
* @reference https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/prefer-to-have-length.md
|
|
109
103
|
*/
|
|
@@ -111,20 +105,18 @@ export interface ITtscLintVitestRules {
|
|
|
111
105
|
/**
|
|
112
106
|
* Validate the shape of Vitest `describe` callbacks.
|
|
113
107
|
*
|
|
114
|
-
* The callback must be synchronous and take no arguments — the
|
|
115
|
-
*
|
|
116
|
-
* the describe level.
|
|
108
|
+
* The callback must be synchronous and take no arguments — the runner ignores
|
|
109
|
+
* returned Promises and `done`-style parameters at the describe level.
|
|
117
110
|
*
|
|
118
111
|
* @reference https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/valid-describe-callback.md
|
|
119
112
|
*/
|
|
120
113
|
"vitest/valid-describe-callback"?: TtscLintRuleSetting;
|
|
121
114
|
/**
|
|
122
|
-
* Validate `expect(...)` arity and matcher chaining: exactly one
|
|
123
|
-
*
|
|
124
|
-
* properly awaited.
|
|
115
|
+
* Validate `expect(...)` arity and matcher chaining: exactly one argument,
|
|
116
|
+
* terminated by a matcher call, and async matchers properly awaited.
|
|
125
117
|
*
|
|
126
|
-
* Malformed expects either throw at runtime or pass without
|
|
127
|
-
*
|
|
118
|
+
* Malformed expects either throw at runtime or pass without asserting
|
|
119
|
+
* anything.
|
|
128
120
|
*
|
|
129
121
|
* @reference https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/valid-expect.md
|
|
130
122
|
*/
|
|
@@ -132,8 +124,8 @@ export interface ITtscLintVitestRules {
|
|
|
132
124
|
/**
|
|
133
125
|
* Require non-empty static Vitest test and `describe` titles.
|
|
134
126
|
*
|
|
135
|
-
* Empty or dynamically-built titles produce unreadable failure
|
|
136
|
-
*
|
|
127
|
+
* Empty or dynamically-built titles produce unreadable failure output and
|
|
128
|
+
* break filter-by-name flags.
|
|
137
129
|
*
|
|
138
130
|
* @reference https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/valid-title.md
|
|
139
131
|
*/
|
package/linthost/config.go
CHANGED
|
@@ -140,7 +140,7 @@ func (c RuleConfig) EnabledRuleConfig() RuleConfig {
|
|
|
140
140
|
out := RuleConfig{}
|
|
141
141
|
for name, sev := range c {
|
|
142
142
|
if sev != SeverityOff {
|
|
143
|
-
out[
|
|
143
|
+
out[normalizeBuiltinRuleName(name)] = sev
|
|
144
144
|
}
|
|
145
145
|
}
|
|
146
146
|
return out
|
|
@@ -157,7 +157,7 @@ func normalizeRuleConfigKeys(c RuleConfig) RuleConfig {
|
|
|
157
157
|
}
|
|
158
158
|
out := RuleConfig{}
|
|
159
159
|
for name, sev := range c {
|
|
160
|
-
out[
|
|
160
|
+
out[normalizeBuiltinRuleName(name)] = sev
|
|
161
161
|
}
|
|
162
162
|
return out
|
|
163
163
|
}
|
|
@@ -196,7 +196,7 @@ func (r InlineRuleResolver) RuleOptions(name string) json.RawMessage {
|
|
|
196
196
|
if raw := r.Options[name]; len(raw) > 0 {
|
|
197
197
|
return raw
|
|
198
198
|
}
|
|
199
|
-
canonical :=
|
|
199
|
+
canonical := normalizeBuiltinRuleName(name)
|
|
200
200
|
if raw := r.Options[canonical]; len(raw) > 0 {
|
|
201
201
|
return raw
|
|
202
202
|
}
|
|
@@ -231,7 +231,7 @@ func (s *ConfigStore) RuleOptions(name string) json.RawMessage {
|
|
|
231
231
|
if raw := s.options[name]; len(raw) > 0 {
|
|
232
232
|
return raw
|
|
233
233
|
}
|
|
234
|
-
canonical :=
|
|
234
|
+
canonical := normalizeBuiltinRuleName(name)
|
|
235
235
|
if raw := s.options[canonical]; len(raw) > 0 {
|
|
236
236
|
return raw
|
|
237
237
|
}
|
|
@@ -270,7 +270,7 @@ func (s *ConfigStore) ResolveRules(fileName string) ResolvedRuleConfig {
|
|
|
270
270
|
continue
|
|
271
271
|
}
|
|
272
272
|
for name, sev := range entry.Rules {
|
|
273
|
-
out[
|
|
273
|
+
out[normalizeBuiltinRuleName(name)] = sev
|
|
274
274
|
}
|
|
275
275
|
}
|
|
276
276
|
return ResolvedRuleConfig{Rules: out}
|
|
@@ -291,7 +291,7 @@ func (s *ConfigStore) ActiveRuleNames() []string {
|
|
|
291
291
|
}
|
|
292
292
|
for name, sev := range entry.Rules {
|
|
293
293
|
if sev != SeverityOff {
|
|
294
|
-
active[
|
|
294
|
+
active[normalizeBuiltinRuleName(name)] = sev
|
|
295
295
|
}
|
|
296
296
|
}
|
|
297
297
|
}
|
|
@@ -314,7 +314,7 @@ func (s *ConfigStore) EnabledRuleConfig() RuleConfig {
|
|
|
314
314
|
if sev == SeverityOff {
|
|
315
315
|
continue
|
|
316
316
|
}
|
|
317
|
-
canonical :=
|
|
317
|
+
canonical := normalizeBuiltinRuleName(name)
|
|
318
318
|
if out[canonical] != SeverityError {
|
|
319
319
|
out[canonical] = sev
|
|
320
320
|
}
|
|
@@ -336,7 +336,7 @@ func (s *ConfigStore) Flatten() RuleConfig {
|
|
|
336
336
|
continue
|
|
337
337
|
}
|
|
338
338
|
for name, sev := range entry.Rules {
|
|
339
|
-
out[
|
|
339
|
+
out[normalizeBuiltinRuleName(name)] = sev
|
|
340
340
|
}
|
|
341
341
|
}
|
|
342
342
|
return out
|
|
@@ -570,9 +570,10 @@ func collectConfigObject(store *ConfigStore, raw any, baseDir, path string, chai
|
|
|
570
570
|
formatValue, hasFormat := obj["format"]
|
|
571
571
|
if hasRules || hasFormat {
|
|
572
572
|
// Expand the format block (if any) into a rules-shaped map, then
|
|
573
|
-
// overlay
|
|
574
|
-
// `
|
|
575
|
-
//
|
|
573
|
+
// overlay the user's explicit `rules` entries. Formatter settings live
|
|
574
|
+
// exclusively in the `format` block: any `format/*` key in `rules` is
|
|
575
|
+
// dropped below (never activates, never overrides the format block), so
|
|
576
|
+
// the overlay only ever layers lint-rule severities on top.
|
|
576
577
|
var formatRulesRaw map[string]any
|
|
577
578
|
if hasFormat {
|
|
578
579
|
formatMap, ok := formatValue.(map[string]any)
|
|
@@ -591,7 +592,18 @@ func collectConfigObject(store *ConfigStore, raw any, baseDir, path string, chai
|
|
|
591
592
|
if !ok {
|
|
592
593
|
return fmt.Errorf("@ttsc/lint: %s.rules must be a rule severity map, got %T", path, rulesValue)
|
|
593
594
|
}
|
|
595
|
+
// `format/*` rules are configured exclusively through the `format`
|
|
596
|
+
// block; they are never valid keys in `rules`. Silently drop any that
|
|
597
|
+
// appear, the same way an unknown rule name is ignored (see
|
|
598
|
+
// parseExternalRuleMapInto): a config must not carry a formatter
|
|
599
|
+
// setting in two places, and a stray `format/*` here is simply not the
|
|
600
|
+
// formatting surface, so it has no effect rather than erroring.
|
|
594
601
|
rulesMap = typedMap
|
|
602
|
+
for key := range rulesMap {
|
|
603
|
+
if isFormatRuleName(key) {
|
|
604
|
+
delete(rulesMap, key)
|
|
605
|
+
}
|
|
606
|
+
}
|
|
595
607
|
}
|
|
596
608
|
merged := mergeRuleMaps(formatRulesRaw, rulesMap)
|
|
597
609
|
if len(merged) > 0 {
|
|
@@ -646,7 +658,7 @@ func collectExternalRuleMapWithOptions(out RuleConfig, opts RuleOptionsMap, raw
|
|
|
646
658
|
if err != nil {
|
|
647
659
|
return fmt.Errorf("@ttsc/lint: rule %q: %w", name, err)
|
|
648
660
|
}
|
|
649
|
-
canonical :=
|
|
661
|
+
canonical := normalizeBuiltinRuleName(name)
|
|
650
662
|
out[canonical] = sev
|
|
651
663
|
if opts != nil && len(ruleOpts) > 0 {
|
|
652
664
|
opts[canonical] = ruleOpts
|
|
@@ -675,12 +687,6 @@ func rejectUnknownConfigKeys(value map[string]any, path string) error {
|
|
|
675
687
|
return nil
|
|
676
688
|
}
|
|
677
689
|
|
|
678
|
-
// normalizeExternalRuleName strips standard TypeScript-ESLint namespaces while
|
|
679
|
-
// preserving @ttsc/lint's canonical kebab/slash rule IDs.
|
|
680
|
-
func normalizeExternalRuleName(name string) string {
|
|
681
|
-
return normalizeBuiltinRuleName(name)
|
|
682
|
-
}
|
|
683
|
-
|
|
684
690
|
// parsePatternList coerces a raw config value to a string slice for use as a
|
|
685
691
|
// `files` or `ignores` pattern list. Accepts a bare string (single-pattern
|
|
686
692
|
// shorthand) or a string array. Empty patterns are rejected eagerly.
|
|
@@ -767,7 +773,7 @@ func LoadConfigResolver(entry *PluginEntry, cwd, tsconfigPath string) (RuleResol
|
|
|
767
773
|
return nil, err
|
|
768
774
|
}
|
|
769
775
|
if discovered == "" {
|
|
770
|
-
return nil, fmt.Errorf("
|
|
776
|
+
return nil, fmt.Errorf("%w (searched upward from %s); create one or set \"configFile\" on the tsconfig plugin entry", errNoLintConfigFile, cwd)
|
|
771
777
|
}
|
|
772
778
|
return loadConfigResolver(discovered)
|
|
773
779
|
}
|
|
@@ -1053,13 +1059,66 @@ func loadJSONConfigFile(location string) (any, error) {
|
|
|
1053
1059
|
return out, nil
|
|
1054
1060
|
}
|
|
1055
1061
|
|
|
1062
|
+
// serializableConfigKeys is the single source of truth for the ITtscLintConfig
|
|
1063
|
+
// keys that survive the JSON round trip from a config-loader subprocess back to
|
|
1064
|
+
// the Go sidecar. Both the .js/.cjs/.mjs loader (loadScriptConfigFile) and the
|
|
1065
|
+
// .ts/.cts/.mts loader (typeScriptConfigLoaderSource) splice this list into the
|
|
1066
|
+
// `toSerializableConfig` key whitelist of their generated scripts, so the set
|
|
1067
|
+
// of copied keys is defined here once rather than duplicated per loader.
|
|
1068
|
+
var serializableConfigKeys = []string{"files", "ignores", "extends", "plugins", "rules", "format"}
|
|
1069
|
+
|
|
1070
|
+
// serializableConfigKeysLiteral renders serializableConfigKeys as a
|
|
1071
|
+
// JS/TS array literal (e.g. `"files", "ignores", ...`) for splicing into the
|
|
1072
|
+
// generated loader scripts' `toSerializableConfig` whitelist.
|
|
1073
|
+
func serializableConfigKeysLiteral() string {
|
|
1074
|
+
quoted := make([]string, len(serializableConfigKeys))
|
|
1075
|
+
for i, key := range serializableConfigKeys {
|
|
1076
|
+
quoted[i] = fmt.Sprintf("%q", key)
|
|
1077
|
+
}
|
|
1078
|
+
return strings.Join(quoted, ", ")
|
|
1079
|
+
}
|
|
1080
|
+
|
|
1081
|
+
// runConfigLoaderCommand runs a prepared config-loader subprocess (`cmd`),
|
|
1082
|
+
// then turns its result into a parsed config object. It owns the shared tail
|
|
1083
|
+
// of both subprocess-backed loaders: capturing stdout, distinguishing a
|
|
1084
|
+
// timeout from a process error (extracting the subprocess stderr when present),
|
|
1085
|
+
// JSON-parsing the output, and rejecting a non-object result. `ctx` is the
|
|
1086
|
+
// timeout context the caller bound `cmd` to; `location` is the config file path
|
|
1087
|
+
// for error messages; `label` is the human-readable subject (e.g. "config
|
|
1088
|
+
// file" or "TypeScript config file") spliced into the load/parse error
|
|
1089
|
+
// prefixes so each loader keeps its own wording.
|
|
1090
|
+
func runConfigLoaderCommand(ctx context.Context, cmd *exec.Cmd, location, label string) (any, error) {
|
|
1091
|
+
output, err := cmd.Output()
|
|
1092
|
+
if err != nil {
|
|
1093
|
+
if ctx.Err() == context.DeadlineExceeded {
|
|
1094
|
+
return nil, fmt.Errorf("@ttsc/lint: load %s %s: timed out after %s", label, location, configLoaderTimeout)
|
|
1095
|
+
}
|
|
1096
|
+
stderr := ""
|
|
1097
|
+
if exit, ok := err.(*exec.ExitError); ok {
|
|
1098
|
+
stderr = strings.TrimSpace(string(exit.Stderr))
|
|
1099
|
+
}
|
|
1100
|
+
if stderr != "" {
|
|
1101
|
+
return nil, fmt.Errorf("@ttsc/lint: load %s %s: %s", label, location, stderr)
|
|
1102
|
+
}
|
|
1103
|
+
return nil, fmt.Errorf("@ttsc/lint: load %s %s: %w", label, location, err)
|
|
1104
|
+
}
|
|
1105
|
+
var out any
|
|
1106
|
+
if err := json.Unmarshal(output, &out); err != nil {
|
|
1107
|
+
return nil, fmt.Errorf("@ttsc/lint: parse %s %s output: %w", label, location, err)
|
|
1108
|
+
}
|
|
1109
|
+
if !isConfigObject(out) {
|
|
1110
|
+
return nil, fmt.Errorf("@ttsc/lint: config file %s must export an ITtscLintConfig object", location)
|
|
1111
|
+
}
|
|
1112
|
+
return out, nil
|
|
1113
|
+
}
|
|
1114
|
+
|
|
1056
1115
|
// loadScriptConfigFile evaluates a .js/.cjs/.mjs config file by running a
|
|
1057
1116
|
// Node subprocess that dynamic-imports the file, resolves the exported config
|
|
1058
1117
|
// through the same 8-hop default/config unwrap used by the TS loader, and
|
|
1059
1118
|
// serializes the result as JSON to stdout. The subprocess has a
|
|
1060
1119
|
// configLoaderTimeout deadline to prevent user code from hanging indefinitely.
|
|
1061
1120
|
func loadScriptConfigFile(location string) (any, error) {
|
|
1062
|
-
|
|
1121
|
+
script := fmt.Sprintf(`
|
|
1063
1122
|
const { pathToFileURL } = require("node:url");
|
|
1064
1123
|
|
|
1065
1124
|
(async () => {
|
|
@@ -1067,8 +1126,8 @@ const { pathToFileURL } = require("node:url");
|
|
|
1067
1126
|
let current = mod;
|
|
1068
1127
|
let allowNamedConfig = true;
|
|
1069
1128
|
// Match the 8-hop walk used by the TypeScript loader at
|
|
1070
|
-
//
|
|
1071
|
-
// interop (e.g.
|
|
1129
|
+
// `+"`"+`typeScriptConfigLoaderSource`+"`"+` so doubly-wrapped CJS/ESM
|
|
1130
|
+
// interop (e.g. `+"`"+`{default:{default:config}}`+"`"+`) is resolved
|
|
1072
1131
|
// consistently across .js/.cjs/.mjs and .ts/.cts/.mts loaders.
|
|
1073
1132
|
for (let i = 0; i < 8; i++) {
|
|
1074
1133
|
if (current !== null && typeof current === "object" && Object.prototype.hasOwnProperty.call(current, "default")) {
|
|
@@ -1096,17 +1155,17 @@ const { pathToFileURL } = require("node:url");
|
|
|
1096
1155
|
// toSerializableConfig copies every ITtscLintConfig key onto a plain object so
|
|
1097
1156
|
// it survives the JSON round trip to the Go sidecar. Every key is copied
|
|
1098
1157
|
// verbatim — files, ignores, extends, plugins, rules, AND format — so a config
|
|
1099
|
-
// whose only key is
|
|
1158
|
+
// whose only key is `+"`"+`format`+"`"+` is not silently dropped.
|
|
1100
1159
|
function toSerializableConfig(value) {
|
|
1101
1160
|
const out = {};
|
|
1102
|
-
for (const key of [
|
|
1161
|
+
for (const key of [%s]) {
|
|
1103
1162
|
if (Object.prototype.hasOwnProperty.call(value, key)) {
|
|
1104
1163
|
out[key] = value[key];
|
|
1105
1164
|
}
|
|
1106
1165
|
}
|
|
1107
1166
|
return out;
|
|
1108
1167
|
}
|
|
1109
|
-
|
|
1168
|
+
`, serializableConfigKeysLiteral())
|
|
1110
1169
|
node := os.Getenv("TTSC_NODE_BINARY")
|
|
1111
1170
|
if node == "" {
|
|
1112
1171
|
node = "node"
|
|
@@ -1114,28 +1173,7 @@ function toSerializableConfig(value) {
|
|
|
1114
1173
|
ctx, cancel := context.WithTimeout(context.Background(), configLoaderTimeout)
|
|
1115
1174
|
defer cancel()
|
|
1116
1175
|
cmd := exec.CommandContext(ctx, node, "-e", script, location)
|
|
1117
|
-
|
|
1118
|
-
if err != nil {
|
|
1119
|
-
if ctx.Err() == context.DeadlineExceeded {
|
|
1120
|
-
return nil, fmt.Errorf("@ttsc/lint: load config file %s: timed out after %s", location, configLoaderTimeout)
|
|
1121
|
-
}
|
|
1122
|
-
stderr := ""
|
|
1123
|
-
if exit, ok := err.(*exec.ExitError); ok {
|
|
1124
|
-
stderr = strings.TrimSpace(string(exit.Stderr))
|
|
1125
|
-
}
|
|
1126
|
-
if stderr != "" {
|
|
1127
|
-
return nil, fmt.Errorf("@ttsc/lint: load config file %s: %s", location, stderr)
|
|
1128
|
-
}
|
|
1129
|
-
return nil, fmt.Errorf("@ttsc/lint: load config file %s: %w", location, err)
|
|
1130
|
-
}
|
|
1131
|
-
var out any
|
|
1132
|
-
if err := json.Unmarshal(output, &out); err != nil {
|
|
1133
|
-
return nil, fmt.Errorf("@ttsc/lint: parse config file %s output: %w", location, err)
|
|
1134
|
-
}
|
|
1135
|
-
if !isConfigObject(out) {
|
|
1136
|
-
return nil, fmt.Errorf("@ttsc/lint: config file %s must export an ITtscLintConfig object", location)
|
|
1137
|
-
}
|
|
1138
|
-
return out, nil
|
|
1176
|
+
return runConfigLoaderCommand(ctx, cmd, location, "config file")
|
|
1139
1177
|
}
|
|
1140
1178
|
|
|
1141
1179
|
// loadTypeScriptConfigFile evaluates a .ts/.cts/.mts config file by writing
|
|
@@ -1194,28 +1232,7 @@ func loadTypeScriptConfigFile(location string) (any, error) {
|
|
|
1194
1232
|
defer cancel()
|
|
1195
1233
|
cmd := ttsxCommandContext(ctx, args...)
|
|
1196
1234
|
cmd.Env = nodeConfigLoaderEnv(location)
|
|
1197
|
-
|
|
1198
|
-
if err != nil {
|
|
1199
|
-
if ctx.Err() == context.DeadlineExceeded {
|
|
1200
|
-
return nil, fmt.Errorf("@ttsc/lint: load TypeScript config file %s: timed out after %s", location, configLoaderTimeout)
|
|
1201
|
-
}
|
|
1202
|
-
stderr := ""
|
|
1203
|
-
if exit, ok := err.(*exec.ExitError); ok {
|
|
1204
|
-
stderr = strings.TrimSpace(string(exit.Stderr))
|
|
1205
|
-
}
|
|
1206
|
-
if stderr != "" {
|
|
1207
|
-
return nil, fmt.Errorf("@ttsc/lint: load TypeScript config file %s: %s", location, stderr)
|
|
1208
|
-
}
|
|
1209
|
-
return nil, fmt.Errorf("@ttsc/lint: load TypeScript config file %s: %w", location, err)
|
|
1210
|
-
}
|
|
1211
|
-
var out any
|
|
1212
|
-
if err := json.Unmarshal(output, &out); err != nil {
|
|
1213
|
-
return nil, fmt.Errorf("@ttsc/lint: parse TypeScript config file %s output: %w", location, err)
|
|
1214
|
-
}
|
|
1215
|
-
if !isConfigObject(out) {
|
|
1216
|
-
return nil, fmt.Errorf("@ttsc/lint: config file %s must export an ITtscLintConfig object", location)
|
|
1217
|
-
}
|
|
1218
|
-
return out, nil
|
|
1235
|
+
return runConfigLoaderCommand(ctx, cmd, location, "TypeScript config file")
|
|
1219
1236
|
}
|
|
1220
1237
|
|
|
1221
1238
|
// isConfigObject reports whether `value` is a top-level config object. A lint
|
|
@@ -1303,14 +1320,14 @@ function hasOwn(value: Record<string, unknown>, key: string): boolean {
|
|
|
1303
1320
|
// whose only key is "format" is not silently dropped.
|
|
1304
1321
|
function toSerializableConfig(value: Record<string, unknown>): Record<string, unknown> {
|
|
1305
1322
|
const out: Record<string, unknown> = {};
|
|
1306
|
-
for (const key of [
|
|
1323
|
+
for (const key of [%s]) {
|
|
1307
1324
|
if (hasOwn(value, key)) {
|
|
1308
1325
|
out[key] = value[key];
|
|
1309
1326
|
}
|
|
1310
1327
|
}
|
|
1311
1328
|
return out;
|
|
1312
1329
|
}
|
|
1313
|
-
`, importLiteral)
|
|
1330
|
+
`, importLiteral, serializableConfigKeysLiteral())
|
|
1314
1331
|
}
|
|
1315
1332
|
|
|
1316
1333
|
// typeScriptConfigLoaderTsconfig generates the JSON content of the ephemeral
|
|
@@ -1731,7 +1748,7 @@ func (c RuleConfig) Severity(name string) Severity {
|
|
|
1731
1748
|
if sev, ok := c[name]; ok {
|
|
1732
1749
|
return sev
|
|
1733
1750
|
}
|
|
1734
|
-
canonical :=
|
|
1751
|
+
canonical := normalizeBuiltinRuleName(name)
|
|
1735
1752
|
if sev, ok := c[canonical]; ok {
|
|
1736
1753
|
return sev
|
|
1737
1754
|
}
|