@ttsc/lint 0.13.0 → 0.14.0-dev.20250530.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +955 -85
- package/lib/defaultFormat.d.ts +15 -8
- package/lib/defaultFormat.js +15 -8
- package/lib/defaultFormat.js.map +1 -1
- package/lib/index.d.ts +46 -0
- package/lib/index.js +60 -37
- package/lib/index.js.map +1 -1
- package/lib/structures/ITtscLintConfig.d.ts +12 -6
- package/lib/structures/TtscLintRuleSetting.d.ts +49 -0
- package/lib/structures/{TtscLintRuleOptions.js → TtscLintRuleSetting.js} +1 -1
- package/lib/structures/TtscLintRuleSetting.js.map +1 -0
- package/lib/structures/format/ITtscLintFormat.d.ts +128 -0
- package/lib/structures/{TtscLintRuleMap.js → format/ITtscLintFormat.js} +1 -1
- package/lib/structures/format/ITtscLintFormat.js.map +1 -0
- package/lib/structures/format/ITtscLintFormatJsDoc.d.ts +17 -0
- package/lib/structures/{ITtscLintFormatConfig.js → format/ITtscLintFormatJsDoc.js} +1 -1
- 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 +3 -4
- package/lib/structures/index.js +3 -4
- package/lib/structures/index.js.map +1 -1
- package/lib/structures/rules/ITtscLintBoundariesRuleOptions.d.ts +95 -0
- package/lib/structures/rules/ITtscLintBoundariesRuleOptions.js +13 -0
- package/lib/structures/rules/ITtscLintBoundariesRuleOptions.js.map +1 -0
- package/lib/structures/rules/ITtscLintBoundariesRules.d.ts +75 -0
- package/lib/structures/rules/ITtscLintBoundariesRules.js +3 -0
- package/lib/structures/rules/ITtscLintBoundariesRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintContributorRules.d.ts +16 -0
- package/lib/structures/rules/ITtscLintContributorRules.js +3 -0
- package/lib/structures/rules/ITtscLintContributorRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintCoreRules.d.ts +1229 -0
- package/lib/structures/rules/ITtscLintCoreRules.js +3 -0
- package/lib/structures/rules/ITtscLintCoreRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintCypressRuleOptions.d.ts +17 -0
- package/lib/structures/rules/ITtscLintCypressRuleOptions.js +10 -0
- package/lib/structures/rules/ITtscLintCypressRuleOptions.js.map +1 -0
- package/lib/structures/rules/ITtscLintCypressRules.d.ts +125 -0
- package/lib/structures/rules/ITtscLintCypressRules.js +3 -0
- package/lib/structures/rules/ITtscLintCypressRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintFunctionalRuleOptions.d.ts +154 -0
- package/lib/structures/rules/ITtscLintFunctionalRuleOptions.js +13 -0
- package/lib/structures/rules/ITtscLintFunctionalRuleOptions.js.map +1 -0
- package/lib/structures/rules/ITtscLintFunctionalRules.d.ts +162 -0
- package/lib/structures/rules/ITtscLintFunctionalRules.js +3 -0
- package/lib/structures/rules/ITtscLintFunctionalRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintJestRules.d.ts +190 -0
- package/lib/structures/rules/ITtscLintJestRules.js +3 -0
- package/lib/structures/rules/ITtscLintJestRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintJsdocRules.d.ts +133 -0
- package/lib/structures/rules/ITtscLintJsdocRules.js +3 -0
- package/lib/structures/rules/ITtscLintJsdocRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintJsxA11yRules.d.ts +294 -0
- package/lib/structures/rules/ITtscLintJsxA11yRules.js +3 -0
- package/lib/structures/rules/ITtscLintJsxA11yRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintNextjsRules.d.ts +180 -0
- package/lib/structures/rules/ITtscLintNextjsRules.js +3 -0
- package/lib/structures/rules/ITtscLintNextjsRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintPlaywrightRules.d.ts +312 -0
- package/lib/structures/rules/ITtscLintPlaywrightRules.js +3 -0
- package/lib/structures/rules/ITtscLintPlaywrightRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintPromiseRules.d.ts +179 -0
- package/lib/structures/rules/ITtscLintPromiseRules.js +3 -0
- package/lib/structures/rules/ITtscLintPromiseRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintReactPerfRuleOptions.d.ts +18 -0
- package/lib/structures/rules/ITtscLintReactPerfRuleOptions.js +8 -0
- package/lib/structures/rules/ITtscLintReactPerfRuleOptions.js.map +1 -0
- package/lib/structures/rules/ITtscLintReactPerfRules.d.ts +49 -0
- package/lib/structures/rules/ITtscLintReactPerfRules.js +3 -0
- package/lib/structures/rules/ITtscLintReactPerfRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintReactRuleOptions.d.ts +37 -0
- package/lib/structures/rules/ITtscLintReactRuleOptions.js +11 -0
- package/lib/structures/rules/ITtscLintReactRuleOptions.js.map +1 -0
- package/lib/structures/rules/ITtscLintReactRules.d.ts +276 -0
- package/lib/structures/rules/ITtscLintReactRules.js +3 -0
- package/lib/structures/rules/ITtscLintReactRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintRegexpRules.d.ts +182 -0
- package/lib/structures/rules/ITtscLintRegexpRules.js +3 -0
- package/lib/structures/rules/ITtscLintRegexpRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintRuleOptionsMap.d.ts +65 -0
- package/lib/structures/rules/ITtscLintRuleOptionsMap.js +3 -0
- package/lib/structures/rules/ITtscLintRuleOptionsMap.js.map +1 -0
- package/lib/structures/rules/ITtscLintRules.d.ts +55 -0
- package/lib/structures/{TtscLintRule.js → rules/ITtscLintRules.js} +1 -1
- package/lib/structures/rules/ITtscLintRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintSecurityRules.d.ts +141 -0
- package/lib/structures/rules/ITtscLintSecurityRules.js +3 -0
- package/lib/structures/rules/ITtscLintSecurityRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintSolidRules.d.ts +178 -0
- package/lib/structures/rules/ITtscLintSolidRules.js +3 -0
- package/lib/structures/rules/ITtscLintSolidRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintStorybookRuleOptions.d.ts +20 -0
- package/lib/structures/rules/ITtscLintStorybookRuleOptions.js +9 -0
- package/lib/structures/rules/ITtscLintStorybookRuleOptions.js.map +1 -0
- package/lib/structures/rules/ITtscLintStorybookRules.d.ts +165 -0
- package/lib/structures/rules/ITtscLintStorybookRules.js +3 -0
- package/lib/structures/rules/ITtscLintStorybookRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintTanstackQueryRules.d.ts +88 -0
- package/lib/structures/rules/ITtscLintTanstackQueryRules.js +3 -0
- package/lib/structures/rules/ITtscLintTanstackQueryRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintTestingLibraryRuleOptions.d.ts +21 -0
- package/lib/structures/rules/ITtscLintTestingLibraryRuleOptions.js +10 -0
- package/lib/structures/rules/ITtscLintTestingLibraryRuleOptions.js.map +1 -0
- package/lib/structures/rules/ITtscLintTestingLibraryRules.d.ts +293 -0
- package/lib/structures/rules/ITtscLintTestingLibraryRules.js +3 -0
- package/lib/structures/rules/ITtscLintTestingLibraryRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintTypeScriptRules.d.ts +1074 -0
- package/lib/structures/rules/ITtscLintTypeScriptRules.js +3 -0
- package/lib/structures/rules/ITtscLintTypeScriptRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintUnicornRules.d.ts +997 -0
- package/lib/structures/rules/ITtscLintUnicornRules.js +3 -0
- package/lib/structures/rules/ITtscLintUnicornRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintVitestRules.d.ts +133 -0
- package/lib/structures/rules/ITtscLintVitestRules.js +3 -0
- package/lib/structures/rules/ITtscLintVitestRules.js.map +1 -0
- package/lib/structures/rules/index.d.ts +31 -0
- package/lib/structures/rules/index.js +48 -0
- package/lib/structures/rules/index.js.map +1 -0
- package/linthost/ast_helpers.go +30 -5
- package/linthost/compile.go +33 -2
- package/linthost/config.go +118 -71
- package/linthost/config_format.go +270 -104
- package/linthost/directives.go +67 -25
- package/linthost/dispatch.go +14 -3
- package/linthost/engine.go +160 -40
- package/linthost/fix.go +10 -3
- package/linthost/flags_gen.go +17 -15
- package/linthost/format.go +222 -25
- package/linthost/format_editor_settings.go +262 -0
- package/linthost/host.go +40 -3
- package/linthost/lsp.go +898 -0
- package/linthost/print_dispatch.go +5 -2
- package/linthost/print_engine.go +5 -5
- package/linthost/print_nodes_call.go +149 -67
- package/linthost/print_nodes_function.go +27 -2
- package/linthost/print_nodes_list.go +40 -5
- package/linthost/print_nodes_object.go +1 -1
- package/linthost/print_nodes_ternary.go +86 -0
- package/linthost/rule_names.go +14 -0
- package/linthost/rules_arrays.go +2 -2
- package/linthost/rules_boundaries.go +532 -0
- package/linthost/rules_camelcase.go +133 -0
- package/linthost/rules_complexity.go +95 -0
- package/linthost/rules_consistent_return.go +130 -0
- package/linthost/rules_console.go +1 -1
- package/linthost/rules_core_extra.go +739 -0
- package/linthost/rules_curly.go +70 -0
- package/linthost/rules_cypress.go +608 -0
- package/linthost/rules_debugger.go +2 -2
- package/linthost/rules_default_case.go +39 -0
- package/linthost/rules_default_case_last.go +46 -0
- package/linthost/rules_dupes.go +3 -3
- package/linthost/rules_empty.go +3 -3
- package/linthost/rules_escape.go +44 -24
- package/linthost/rules_eval.go +2 -2
- package/linthost/rules_finally.go +2 -2
- 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 +595 -0
- package/linthost/rules_format_indent.go +372 -0
- package/linthost/rules_format_jsdoc.go +5 -5
- 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 +66 -55
- package/linthost/rules_format_quote_props.go +169 -0
- package/linthost/rules_format_quotes.go +76 -30
- package/linthost/rules_format_semi.go +186 -11
- package/linthost/rules_format_sort_imports.go +437 -118
- package/linthost/rules_format_statement_split.go +343 -0
- package/linthost/rules_format_ternary_nullish_parens.go +77 -0
- package/linthost/rules_format_trailing_comma.go +22 -3
- package/linthost/rules_format_whitespace.go +336 -0
- package/linthost/rules_functional.go +967 -0
- package/linthost/rules_gap.go +24 -45
- package/linthost/rules_grouped_accessor_pairs.go +87 -0
- package/linthost/rules_guard_for_in.go +198 -0
- package/linthost/rules_id_length.go +77 -0
- package/linthost/rules_imports.go +70 -2
- package/linthost/rules_init_declarations.go +53 -0
- package/linthost/rules_jest.go +618 -0
- package/linthost/rules_jsdoc.go +502 -0
- package/linthost/rules_jsx_a11y.go +1264 -0
- package/linthost/rules_logic.go +12 -12
- package/linthost/rules_loops.go +1 -1
- package/linthost/rules_max_classes_per_file.go +58 -0
- package/linthost/rules_max_depth.go +83 -0
- package/linthost/rules_max_lines.go +101 -0
- package/linthost/rules_max_lines_per_function.go +57 -0
- package/linthost/rules_max_nested_callbacks.go +61 -0
- package/linthost/rules_max_params.go +49 -0
- package/linthost/rules_max_statements.go +59 -0
- package/linthost/rules_misc.go +1 -1
- package/linthost/rules_nextjs.go +697 -0
- package/linthost/rules_no_else_return.go +75 -0
- package/linthost/rules_no_empty_named_blocks.go +91 -0
- package/linthost/rules_no_extend_native.go +51 -0
- package/linthost/rules_no_import_assign.go +140 -0
- package/linthost/rules_no_invalid_this.go +52 -0
- package/linthost/rules_no_loop_func.go +85 -0
- package/linthost/rules_no_magic_numbers.go +123 -0
- package/linthost/rules_no_mixed_operators.go +80 -0
- package/linthost/rules_no_param_reassign.go +98 -0
- package/linthost/rules_no_redeclare.go +270 -0
- package/linthost/rules_no_restricted_imports.go +105 -0
- package/linthost/rules_no_restricted_syntax.go +49 -0
- package/linthost/rules_no_shadow.go +147 -0
- package/linthost/rules_no_unreachable.go +77 -0
- package/linthost/rules_no_useless_assignment.go +120 -0
- package/linthost/rules_no_useless_constructor.go +245 -0
- package/linthost/rules_no_useless_return.go +51 -0
- package/linthost/rules_params.go +1 -1
- package/linthost/rules_playwright.go +788 -0
- package/linthost/rules_prefer_arrow_callback.go +124 -0
- package/linthost/rules_prefer_destructuring.go +98 -0
- package/linthost/rules_prefer_named_capture_group.go +129 -0
- package/linthost/rules_prefer_rest_params.go +94 -0
- package/linthost/rules_problems.go +41 -30
- package/linthost/rules_promise.go +1057 -2
- package/linthost/rules_protos.go +2 -2
- package/linthost/rules_react.go +773 -0
- package/linthost/rules_react_extras.go +227 -0
- package/linthost/rules_react_hooks.go +848 -0
- package/linthost/rules_react_perf.go +293 -0
- package/linthost/rules_react_refresh.go +583 -0
- package/linthost/rules_regexp.go +410 -0
- package/linthost/rules_security.go +830 -0
- package/linthost/rules_self.go +2 -2
- package/linthost/rules_solid.go +1073 -0
- package/linthost/rules_sort_imports.go +69 -0
- package/linthost/rules_sort_keys.go +134 -0
- package/linthost/rules_storybook.go +1176 -0
- package/linthost/rules_strings.go +4 -4
- package/linthost/rules_suggestions.go +38 -38
- package/linthost/rules_tanstack_query.go +844 -0
- package/linthost/rules_testing_library.go +1204 -0
- package/linthost/rules_throw.go +1 -1
- package/linthost/rules_ts.go +19 -19
- package/linthost/rules_ts_async.go +399 -0
- package/linthost/rules_ts_class_literal_property_style.go +115 -0
- package/linthost/rules_ts_consistent_type_exports.go +256 -0
- package/linthost/rules_ts_explicit_function_return_type.go +67 -0
- package/linthost/rules_ts_extra.go +159 -36
- package/linthost/rules_ts_no_base_to_string.go +218 -0
- package/linthost/rules_ts_no_confusing_void.go +72 -0
- package/linthost/rules_ts_no_deprecated.go +195 -0
- package/linthost/rules_ts_no_for_in_array.go +84 -0
- package/linthost/rules_ts_no_magic_numbers.go +124 -0
- package/linthost/rules_ts_no_meaningless_void_operator.go +84 -0
- package/linthost/rules_ts_no_misused_spread.go +104 -0
- package/linthost/rules_ts_no_redundant_type_constituents.go +113 -0
- package/linthost/rules_ts_no_restricted_types.go +62 -0
- package/linthost/rules_ts_no_unnecessary_boolean_literal_compare.go +129 -0
- package/linthost/rules_ts_no_unnecessary_condition.go +250 -0
- package/linthost/rules_ts_no_unnecessary_qualifier.go +118 -0
- package/linthost/rules_ts_no_unnecessary_template_expression.go +178 -0
- package/linthost/rules_ts_no_unnecessary_type_arguments.go +234 -0
- package/linthost/rules_ts_no_unnecessary_type_assertion.go +157 -0
- package/linthost/rules_ts_no_unsafe_argument.go +82 -0
- package/linthost/rules_ts_no_unsafe_assignment.go +102 -0
- package/linthost/rules_ts_no_unsafe_call.go +82 -0
- package/linthost/rules_ts_no_unsafe_enum_comparison.go +235 -0
- package/linthost/rules_ts_no_unsafe_member_access.go +58 -0
- package/linthost/rules_ts_no_unsafe_return.go +126 -0
- package/linthost/rules_ts_no_unsafe_unary_minus.go +81 -0
- package/linthost/rules_ts_no_useless_constructor.go +52 -0
- package/linthost/rules_ts_non_nullable_type_assertion_style.go +108 -0
- package/linthost/rules_ts_parameter_properties.go +38 -0
- package/linthost/rules_ts_prefer_find.go +178 -0
- package/linthost/rules_ts_prefer_includes.go +255 -0
- package/linthost/rules_ts_prefer_nullish_coalescing.go +104 -0
- package/linthost/rules_ts_prefer_optional_chain.go +228 -0
- package/linthost/rules_ts_prefer_promise_reject_errors.go +176 -0
- package/linthost/rules_ts_prefer_readonly.go +73 -0
- package/linthost/rules_ts_prefer_reduce_type_parameter.go +116 -0
- package/linthost/rules_ts_prefer_regexp_exec.go +122 -0
- package/linthost/rules_ts_prefer_return_this_type.go +135 -0
- package/linthost/rules_ts_prefer_string_starts_ends_with.go +360 -0
- package/linthost/rules_ts_promise_function_async.go +77 -0
- package/linthost/rules_ts_related_getter_setter_pairs.go +113 -0
- package/linthost/rules_ts_require_array_sort_compare.go +96 -0
- package/linthost/rules_ts_restrict_plus_operands.go +127 -0
- package/linthost/rules_ts_restrict_template_expressions.go +95 -0
- package/linthost/rules_ts_simple.go +387 -0
- package/linthost/rules_ts_sort_type_constituents.go +144 -0
- package/linthost/rules_ts_strict_boolean_expressions.go +157 -0
- package/linthost/rules_ts_switch_exhaustiveness_check.go +147 -0
- package/linthost/rules_ts_unbound_method.go +126 -0
- package/linthost/rules_tsdoc.go +136 -0
- package/linthost/rules_unicorn_better_regex.go +27 -0
- package/linthost/rules_unicorn_catch_error_name.go +46 -0
- package/linthost/rules_unicorn_consistent_assert.go +47 -0
- package/linthost/rules_unicorn_consistent_date_clone.go +54 -0
- package/linthost/rules_unicorn_consistent_destructuring.go +25 -0
- package/linthost/rules_unicorn_consistent_empty_array_spread.go +62 -0
- package/linthost/rules_unicorn_consistent_existence_index_check.go +80 -0
- package/linthost/rules_unicorn_consistent_function_scoping.go +25 -0
- package/linthost/rules_unicorn_consistent_template_literal_escape.go +25 -0
- package/linthost/rules_unicorn_custom_error_definition.go +138 -0
- package/linthost/rules_unicorn_empty_brace_spaces.go +73 -0
- package/linthost/rules_unicorn_error_message.go +64 -0
- package/linthost/rules_unicorn_escape_case.go +51 -0
- package/linthost/rules_unicorn_expiring_todo_comments.go +78 -0
- package/linthost/rules_unicorn_explicit_length_check.go +88 -0
- package/linthost/rules_unicorn_filename_case.go +29 -0
- package/linthost/rules_unicorn_import_style.go +28 -0
- package/linthost/rules_unicorn_isolated_functions.go +29 -0
- package/linthost/rules_unicorn_new_for_builtins.go +87 -0
- package/linthost/rules_unicorn_no_abusive_eslint_disable.go +63 -0
- package/linthost/rules_unicorn_no_accessor_recursion.go +115 -0
- package/linthost/rules_unicorn_no_anonymous_default_export.go +74 -0
- package/linthost/rules_unicorn_no_array_callback_reference.go +65 -0
- package/linthost/rules_unicorn_no_array_for_each.go +40 -0
- package/linthost/rules_unicorn_no_array_method_this_argument.go +61 -0
- package/linthost/rules_unicorn_no_array_reduce.go +41 -0
- package/linthost/rules_unicorn_no_array_reverse.go +44 -0
- package/linthost/rules_unicorn_no_array_sort.go +43 -0
- package/linthost/rules_unicorn_no_await_expression_member.go +40 -0
- package/linthost/rules_unicorn_no_await_in_promise_methods.go +69 -0
- package/linthost/rules_unicorn_no_console_spaces.go +61 -0
- package/linthost/rules_unicorn_no_document_cookie.go +41 -0
- package/linthost/rules_unicorn_no_empty_file.go +44 -0
- package/linthost/rules_unicorn_no_for_loop.go +102 -0
- package/linthost/rules_unicorn_no_hex_escape.go +42 -0
- package/linthost/rules_unicorn_no_immediate_mutation.go +90 -0
- package/linthost/rules_unicorn_no_instanceof_builtins.go +66 -0
- package/linthost/rules_unicorn_no_invalid_fetch_options.go +79 -0
- package/linthost/rules_unicorn_no_invalid_remove_event_listener.go +51 -0
- package/linthost/rules_unicorn_no_keyword_prefix.go +101 -0
- package/linthost/rules_unicorn_no_lonely_if.go +44 -0
- package/linthost/rules_unicorn_no_magic_array_flat_depth.go +51 -0
- package/linthost/rules_unicorn_no_named_default.go +54 -0
- package/linthost/rules_unicorn_no_negated_condition.go +85 -0
- package/linthost/rules_unicorn_no_negation_in_equality_check.go +50 -0
- package/linthost/rules_unicorn_no_nested_ternary.go +43 -0
- package/linthost/rules_unicorn_no_new_array.go +30 -0
- package/linthost/rules_unicorn_no_new_buffer.go +31 -0
- package/linthost/rules_unicorn_no_null.go +24 -0
- package/linthost/rules_unicorn_no_object_as_default_parameter.go +48 -0
- package/linthost/rules_unicorn_no_process_exit.go +43 -0
- package/linthost/rules_unicorn_no_single_promise_in_promise_methods.go +59 -0
- package/linthost/rules_unicorn_no_static_only_class.go +56 -0
- package/linthost/rules_unicorn_no_thenable.go +74 -0
- package/linthost/rules_unicorn_no_this_assignment.go +35 -0
- package/linthost/rules_unicorn_no_typeof_undefined.go +58 -0
- package/linthost/rules_unicorn_no_unnecessary_array_flat_depth.go +49 -0
- package/linthost/rules_unicorn_no_unnecessary_array_splice_count.go +70 -0
- package/linthost/rules_unicorn_no_unnecessary_await.go +51 -0
- package/linthost/rules_unicorn_no_unnecessary_polyfills.go +32 -0
- package/linthost/rules_unicorn_no_unnecessary_slice_end.go +48 -0
- package/linthost/rules_unicorn_no_unreadable_array_destructuring.go +115 -0
- package/linthost/rules_unicorn_no_unreadable_iife.go +50 -0
- package/linthost/rules_unicorn_no_unused_properties.go +30 -0
- package/linthost/rules_unicorn_no_useless_collection_argument.go +63 -0
- package/linthost/rules_unicorn_no_useless_error_capture_stack_trace.go +46 -0
- package/linthost/rules_unicorn_no_useless_fallback_in_spread.go +81 -0
- package/linthost/rules_unicorn_no_useless_iterator_to_array.go +72 -0
- package/linthost/rules_unicorn_no_useless_length_check.go +144 -0
- package/linthost/rules_unicorn_no_useless_promise_resolve_reject.go +81 -0
- package/linthost/rules_unicorn_no_useless_spread.go +67 -0
- package/linthost/rules_unicorn_no_useless_switch_case.go +55 -0
- package/linthost/rules_unicorn_no_useless_undefined.go +55 -0
- package/linthost/rules_unicorn_no_zero_fractions.go +52 -0
- package/linthost/rules_unicorn_number_literal_case.go +69 -0
- package/linthost/rules_unicorn_numeric_separators_style.go +75 -0
- package/linthost/rules_unicorn_prefer_add_event_listener.go +66 -0
- package/linthost/rules_unicorn_prefer_array_find.go +51 -0
- package/linthost/rules_unicorn_prefer_array_flat.go +52 -0
- package/linthost/rules_unicorn_prefer_array_flat_map.go +63 -0
- package/linthost/rules_unicorn_prefer_array_index_of.go +147 -0
- package/linthost/rules_unicorn_prefer_array_some.go +67 -0
- package/linthost/rules_unicorn_prefer_at.go +77 -0
- package/linthost/rules_unicorn_prefer_bigint_literals.go +77 -0
- package/linthost/rules_unicorn_prefer_blob_reading_methods.go +44 -0
- package/linthost/rules_unicorn_prefer_class_fields.go +93 -0
- package/linthost/rules_unicorn_prefer_classlist_toggle.go +120 -0
- package/linthost/rules_unicorn_prefer_code_point.go +49 -0
- package/linthost/rules_unicorn_prefer_date_now.go +78 -0
- package/linthost/rules_unicorn_prefer_default_parameters.go +144 -0
- package/linthost/rules_unicorn_prefer_dom_node_append.go +40 -0
- package/linthost/rules_unicorn_prefer_dom_node_dataset.go +55 -0
- package/linthost/rules_unicorn_prefer_dom_node_remove.go +41 -0
- package/linthost/rules_unicorn_prefer_dom_node_text_content.go +37 -0
- package/linthost/rules_unicorn_prefer_event_target.go +36 -0
- package/linthost/rules_unicorn_prefer_export_from.go +129 -0
- package/linthost/rules_unicorn_prefer_global_this.go +127 -0
- package/linthost/rules_unicorn_prefer_import_meta_properties.go +66 -0
- package/linthost/rules_unicorn_prefer_includes.go +149 -0
- package/linthost/rules_unicorn_prefer_json_parse_buffer.go +65 -0
- package/linthost/rules_unicorn_prefer_keyboard_event_key.go +38 -0
- package/linthost/rules_unicorn_prefer_logical_operator_over_ternary.go +48 -0
- package/linthost/rules_unicorn_prefer_math_min_max.go +60 -0
- package/linthost/rules_unicorn_prefer_math_trunc.go +62 -0
- package/linthost/rules_unicorn_prefer_modern_dom_apis.go +47 -0
- package/linthost/rules_unicorn_prefer_modern_math_apis.go +70 -0
- package/linthost/rules_unicorn_prefer_module.go +50 -0
- package/linthost/rules_unicorn_prefer_native_coercion_functions.go +114 -0
- package/linthost/rules_unicorn_prefer_negative_index.go +74 -0
- package/linthost/rules_unicorn_prefer_node_protocol.go +122 -0
- package/linthost/rules_unicorn_prefer_number_properties.go +88 -0
- package/linthost/rules_unicorn_prefer_object_from_entries.go +55 -0
- package/linthost/rules_unicorn_prefer_optional_catch_binding.go +62 -0
- package/linthost/rules_unicorn_prefer_prototype_methods.go +54 -0
- package/linthost/rules_unicorn_prefer_query_selector.go +56 -0
- package/linthost/rules_unicorn_prefer_reflect_apply.go +36 -0
- package/linthost/rules_unicorn_prefer_regexp_test_rule.go +80 -0
- package/linthost/rules_unicorn_prefer_response_static_json.go +53 -0
- package/linthost/rules_unicorn_prefer_set_has.go +42 -0
- package/linthost/rules_unicorn_prefer_set_size.go +48 -0
- package/linthost/rules_unicorn_prefer_simple_condition_first.go +34 -0
- package/linthost/rules_unicorn_prefer_single_call.go +96 -0
- package/linthost/rules_unicorn_prefer_spread.go +51 -0
- package/linthost/rules_unicorn_prefer_string_raw.go +43 -0
- package/linthost/rules_unicorn_prefer_string_replace_all.go +95 -0
- package/linthost/rules_unicorn_prefer_string_slice.go +43 -0
- package/linthost/rules_unicorn_prefer_string_starts_ends_with.go +148 -0
- package/linthost/rules_unicorn_prefer_string_trim_start_end.go +48 -0
- package/linthost/rules_unicorn_prefer_structured_clone.go +71 -0
- package/linthost/rules_unicorn_prefer_switch.go +103 -0
- package/linthost/rules_unicorn_prefer_ternary.go +71 -0
- package/linthost/rules_unicorn_prefer_top_level_await.go +72 -0
- package/linthost/rules_unicorn_prefer_type_error.go +127 -0
- package/linthost/rules_unicorn_prevent_abbreviations.go +127 -0
- package/linthost/rules_unicorn_relative_url_style.go +49 -0
- package/linthost/rules_unicorn_require_array_join_separator.go +45 -0
- package/linthost/rules_unicorn_require_module_attributes.go +54 -0
- package/linthost/rules_unicorn_require_module_specifiers.go +55 -0
- package/linthost/rules_unicorn_require_number_to_fixed_digits_argument.go +43 -0
- package/linthost/rules_unicorn_require_post_message_target_origin.go +44 -0
- package/linthost/rules_unicorn_string_content.go +27 -0
- package/linthost/rules_unicorn_switch_case_braces.go +42 -0
- package/linthost/rules_unicorn_switch_case_break_position.go +31 -0
- package/linthost/rules_unicorn_template_indent.go +28 -0
- package/linthost/rules_unicorn_text_encoding_identifier_case.go +72 -0
- package/linthost/rules_unicorn_throw_new_error.go +61 -0
- package/linthost/rules_var.go +10 -4
- package/linthost/rules_vitest.go +568 -0
- package/package.json +3 -3
- package/plugin/main.go +49 -3
- package/rule/astutil/astutil.go +10 -3
- package/rule/rule.go +12 -10
- package/src/defaultFormat.ts +17 -10
- package/src/index.ts +65 -43
- package/src/structures/ITtscLintConfig.ts +14 -8
- package/src/structures/TtscLintRuleSetting.ts +55 -0
- package/src/structures/format/ITtscLintFormat.ts +141 -0
- package/src/structures/format/ITtscLintFormatJsDoc.ts +18 -0
- package/src/structures/format/ITtscLintFormatSortImports.ts +62 -0
- package/src/structures/format/index.ts +3 -0
- package/src/structures/index.ts +3 -4
- package/src/structures/rules/ITtscLintBoundariesRuleOptions.ts +117 -0
- package/src/structures/rules/ITtscLintBoundariesRules.ts +91 -0
- package/src/structures/rules/ITtscLintContributorRules.ts +20 -0
- package/src/structures/rules/ITtscLintCoreRules.ts +1378 -0
- package/src/structures/rules/ITtscLintCypressRuleOptions.ts +18 -0
- package/src/structures/rules/ITtscLintCypressRules.ts +141 -0
- package/src/structures/rules/ITtscLintFunctionalRuleOptions.ts +200 -0
- package/src/structures/rules/ITtscLintFunctionalRules.ts +197 -0
- package/src/structures/rules/ITtscLintJestRules.ts +209 -0
- package/src/structures/rules/ITtscLintJsdocRules.ts +146 -0
- package/src/structures/rules/ITtscLintJsxA11yRules.ts +331 -0
- package/src/structures/rules/ITtscLintNextjsRules.ts +201 -0
- package/src/structures/rules/ITtscLintPlaywrightRules.ts +343 -0
- package/src/structures/rules/ITtscLintPromiseRules.ts +196 -0
- package/src/structures/rules/ITtscLintReactPerfRuleOptions.ts +19 -0
- package/src/structures/rules/ITtscLintReactPerfRules.ts +53 -0
- package/src/structures/rules/ITtscLintReactRuleOptions.ts +41 -0
- package/src/structures/rules/ITtscLintReactRules.ts +308 -0
- package/src/structures/rules/ITtscLintRegexpRules.ts +204 -0
- package/src/structures/rules/ITtscLintRuleOptionsMap.ts +88 -0
- package/src/structures/rules/ITtscLintRules.ts +77 -0
- package/src/structures/rules/ITtscLintSecurityRules.ts +155 -0
- package/src/structures/rules/ITtscLintSolidRules.ts +199 -0
- package/src/structures/rules/ITtscLintStorybookRuleOptions.ts +22 -0
- package/src/structures/rules/ITtscLintStorybookRules.ts +184 -0
- package/src/structures/rules/ITtscLintTanstackQueryRules.ts +96 -0
- package/src/structures/rules/ITtscLintTestingLibraryRuleOptions.ts +23 -0
- package/src/structures/rules/ITtscLintTestingLibraryRules.ts +325 -0
- package/src/structures/rules/ITtscLintTypeScriptRules.ts +1172 -0
- package/src/structures/rules/ITtscLintUnicornRules.ts +1143 -0
- package/src/structures/rules/ITtscLintVitestRules.ts +146 -0
- package/src/structures/rules/index.ts +31 -0
- package/lib/structures/ITtscLintFormatConfig.d.ts +0 -153
- package/lib/structures/ITtscLintFormatConfig.js.map +0 -1
- package/lib/structures/TtscLintRule.d.ts +0 -17
- package/lib/structures/TtscLintRule.js.map +0 -1
- package/lib/structures/TtscLintRuleMap.d.ts +0 -46
- package/lib/structures/TtscLintRuleMap.js.map +0 -1
- package/lib/structures/TtscLintRuleOptions.d.ts +0 -137
- package/lib/structures/TtscLintRuleOptions.js.map +0 -1
- package/src/structures/ITtscLintFormatConfig.ts +0 -168
- package/src/structures/TtscLintRule.ts +0 -160
- package/src/structures/TtscLintRuleMap.ts +0 -55
- package/src/structures/TtscLintRuleOptions.ts +0 -151
|
@@ -3,13 +3,14 @@ package linthost
|
|
|
3
3
|
import (
|
|
4
4
|
"encoding/json"
|
|
5
5
|
"fmt"
|
|
6
|
+
"strings"
|
|
6
7
|
)
|
|
7
8
|
|
|
8
9
|
// expandFormatBlock translates a Prettier-style `format` block into the
|
|
9
10
|
// per-rule severity + options shape the existing rule parsers consume.
|
|
10
11
|
// The result is a `map[string]any` that mirrors what a user would
|
|
11
|
-
// have written under `rules` directly
|
|
12
|
-
// `"format/semi": ["off", {"prefer": "always"}]
|
|
12
|
+
// have written under `rules` directly, entries like
|
|
13
|
+
// `"format/semi": ["off", {"prefer": "always"}]`, so the caller
|
|
13
14
|
// can route it through either `ParseRulesWithOptions` or
|
|
14
15
|
// `parseExternalRuleMapInto` without duplicating option-decoding logic.
|
|
15
16
|
//
|
|
@@ -20,16 +21,27 @@ import (
|
|
|
20
21
|
//
|
|
21
22
|
// The block's enablement matrix:
|
|
22
23
|
//
|
|
23
|
-
// - `format/semi
|
|
24
|
-
// - `format/quotes
|
|
25
|
-
// - `format/
|
|
26
|
-
// - `format/
|
|
27
|
-
// - `format/
|
|
28
|
-
// - `format/
|
|
24
|
+
// - `format/semi`, always on. `semi: false` flips to `prefer: "never"`.
|
|
25
|
+
// - `format/quotes`, always on. `singleQuote: true` flips to `prefer: "single"`.
|
|
26
|
+
// - `format/arrow-parens`, always on. `arrowParens: "avoid"` strips a single bare-identifier arrow parameter's parens; default "always" adds them.
|
|
27
|
+
// - `format/bracket-spacing`, always on. `bracketSpacing: false` removes the inner space of single-line object/destructure/import/export/type braces; default true keeps it.
|
|
28
|
+
// - `format/quote-props`, always on. `quoteProps: "as-needed"` (default) unquotes identifier object keys; "consistent" keeps all keys quoted when any needs it; "preserve" leaves quoting alone.
|
|
29
|
+
// - `format/trailing-comma`, always on with the requested mode.
|
|
30
|
+
// - `format/print-width`, always on, driven by printWidth/tabWidth/useTabs/endOfLine.
|
|
31
|
+
// - `format/clause-join`, always on, joins a single-statement clause body that fits printWidth.
|
|
32
|
+
// - `format/declaration-header`, always on, reflows a class/interface header's type params and heritage clauses.
|
|
33
|
+
// - `format/ternary-nullish-parens`, always on, parenthesizes a `??` operand of a conditional expression.
|
|
34
|
+
// - `format/orphan-semi`, always on; under semi:false, merges a leading-semicolon ASI guard onto its statement.
|
|
35
|
+
// - `format/parameter-properties`, always on, breaks a constructor's parameter list when it has parameter properties.
|
|
36
|
+
// - `format/statement-split`, always on, driven by tabWidth/useTabs/endOfLine.
|
|
37
|
+
// - `format/indent`, always on, driven by tabWidth/useTabs/endOfLine.
|
|
38
|
+
// - `format/whitespace`, always on, driven by endOfLine.
|
|
39
|
+
// - `format/sort-imports`, opt-in by setting `sortImports`.
|
|
40
|
+
// - `format/jsdoc`, always-on; `jsDoc: false` opts out, an object customizes.
|
|
29
41
|
//
|
|
30
42
|
// The returned map is the raw form rules parsers expect. Callers MUST
|
|
31
43
|
// merge any user-supplied `rules` map on top of this one (rules-wins
|
|
32
|
-
// semantics) before invoking the existing parsers
|
|
44
|
+
// semantics) before invoking the existing parsers, `mergeRuleMaps`
|
|
33
45
|
// below performs the merge with the right precedence.
|
|
34
46
|
func expandFormatBlock(raw map[string]any) (map[string]any, error) {
|
|
35
47
|
if raw == nil {
|
|
@@ -47,7 +59,7 @@ func expandFormatBlock(raw map[string]any) (map[string]any, error) {
|
|
|
47
59
|
}
|
|
48
60
|
out := map[string]any{}
|
|
49
61
|
|
|
50
|
-
//
|
|
62
|
+
// formatSemi
|
|
51
63
|
semiPrefer := "always"
|
|
52
64
|
if v, ok := raw["semi"]; ok {
|
|
53
65
|
b, err := asBool("format.semi", v)
|
|
@@ -60,7 +72,11 @@ func expandFormatBlock(raw map[string]any) (map[string]any, error) {
|
|
|
60
72
|
}
|
|
61
73
|
out["format/semi"] = ruleEntry(map[string]any{"prefer": semiPrefer})
|
|
62
74
|
|
|
63
|
-
//
|
|
75
|
+
// formatOrphanSemi, always on; mirrors the effective semi setting so
|
|
76
|
+
// it only merges the leading-semicolon ASI guard under semi:false.
|
|
77
|
+
out["format/orphan-semi"] = ruleEntry(map[string]any{"semi": semiPrefer == "always"})
|
|
78
|
+
|
|
79
|
+
// formatQuotes
|
|
64
80
|
quotesPrefer := "double"
|
|
65
81
|
if v, ok := raw["singleQuote"]; ok {
|
|
66
82
|
b, err := asBool("format.singleQuote", v)
|
|
@@ -73,7 +89,57 @@ func expandFormatBlock(raw map[string]any) (map[string]any, error) {
|
|
|
73
89
|
}
|
|
74
90
|
out["format/quotes"] = ruleEntry(map[string]any{"prefer": quotesPrefer})
|
|
75
91
|
|
|
76
|
-
//
|
|
92
|
+
// formatArrowParens, always on. Mirrors Prettier's arrowParens; the
|
|
93
|
+
// default "always" parenthesizes a single bare-identifier arrow parameter,
|
|
94
|
+
// "avoid" strips the parens.
|
|
95
|
+
arrowPrefer := "always"
|
|
96
|
+
if v, ok := raw["arrowParens"]; ok {
|
|
97
|
+
s, err := asString("format.arrowParens", v)
|
|
98
|
+
if err != nil {
|
|
99
|
+
return nil, err
|
|
100
|
+
}
|
|
101
|
+
switch s {
|
|
102
|
+
case "always", "avoid":
|
|
103
|
+
arrowPrefer = s
|
|
104
|
+
default:
|
|
105
|
+
return nil, fmt.Errorf("@ttsc/lint: format.arrowParens must be \"always\" or \"avoid\"; got %q", s)
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
out["format/arrow-parens"] = ruleEntry(map[string]any{"prefer": arrowPrefer})
|
|
109
|
+
|
|
110
|
+
// formatBracketSpacing, always on. Mirrors Prettier's bracketSpacing;
|
|
111
|
+
// the default true pads single-line object/destructure/import/export/type
|
|
112
|
+
// braces with one inner space, false removes it.
|
|
113
|
+
bracketSpacing := true
|
|
114
|
+
if v, ok := raw["bracketSpacing"]; ok {
|
|
115
|
+
b, err := asBool("format.bracketSpacing", v)
|
|
116
|
+
if err != nil {
|
|
117
|
+
return nil, err
|
|
118
|
+
}
|
|
119
|
+
bracketSpacing = b
|
|
120
|
+
}
|
|
121
|
+
out["format/bracket-spacing"] = ruleEntry(map[string]any{"spacing": bracketSpacing})
|
|
122
|
+
|
|
123
|
+
// formatQuoteProps, always on. Mirrors Prettier's quoteProps; the default
|
|
124
|
+
// "as-needed" unquotes object keys that are valid identifiers, "consistent"
|
|
125
|
+
// keeps every key quoted when any one needs it, "preserve" leaves quoting
|
|
126
|
+
// untouched.
|
|
127
|
+
quoteProps := "as-needed"
|
|
128
|
+
if v, ok := raw["quoteProps"]; ok {
|
|
129
|
+
s, err := asString("format.quoteProps", v)
|
|
130
|
+
if err != nil {
|
|
131
|
+
return nil, err
|
|
132
|
+
}
|
|
133
|
+
switch s {
|
|
134
|
+
case "as-needed", "consistent", "preserve":
|
|
135
|
+
quoteProps = s
|
|
136
|
+
default:
|
|
137
|
+
return nil, fmt.Errorf("@ttsc/lint: format.quoteProps must be \"as-needed\", \"consistent\", or \"preserve\"; got %q", s)
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
out["format/quote-props"] = ruleEntry(map[string]any{"mode": quoteProps})
|
|
141
|
+
|
|
142
|
+
// formatTrailingComma
|
|
77
143
|
tcMode := "all"
|
|
78
144
|
if v, ok := raw["trailingComma"]; ok {
|
|
79
145
|
s, err := asString("format.trailingComma", v)
|
|
@@ -89,15 +155,20 @@ func expandFormatBlock(raw map[string]any) (map[string]any, error) {
|
|
|
89
155
|
}
|
|
90
156
|
out["format/trailing-comma"] = ruleEntry(map[string]any{"mode": tcMode})
|
|
91
157
|
|
|
92
|
-
//
|
|
158
|
+
// formatPrintWidth
|
|
93
159
|
//
|
|
94
160
|
// `trailingComma` is mirrored into the print-width rule's options so
|
|
95
161
|
// the printer's broken-list reflow emits the same trailing-comma
|
|
96
162
|
// shape `format/trailing-comma` does. Without the mirror the two
|
|
97
163
|
// rules disagree on `es5` / `none` projects and oscillate on every
|
|
98
|
-
// cascade pass
|
|
164
|
+
// cascade pass, the trailing-comma rule says "no comma" while the
|
|
99
165
|
// printer adds one back. See `printArgList` in print_nodes_call.go.
|
|
100
|
-
|
|
166
|
+
layoutOpts, err := collectLayoutOpts(raw)
|
|
167
|
+
if err != nil {
|
|
168
|
+
return nil, err
|
|
169
|
+
}
|
|
170
|
+
pwOpts := cloneStringAnyMap(layoutOpts)
|
|
171
|
+
pwOpts["trailingComma"] = tcMode
|
|
101
172
|
if v, ok := raw["printWidth"]; ok {
|
|
102
173
|
n, err := asInt("format.printWidth", v)
|
|
103
174
|
if err != nil {
|
|
@@ -108,116 +179,153 @@ func expandFormatBlock(raw map[string]any) (map[string]any, error) {
|
|
|
108
179
|
}
|
|
109
180
|
pwOpts["printWidth"] = n
|
|
110
181
|
}
|
|
111
|
-
if v, ok := raw["tabWidth"]; ok {
|
|
112
|
-
n, err := asInt("format.tabWidth", v)
|
|
113
|
-
if err != nil {
|
|
114
|
-
return nil, err
|
|
115
|
-
}
|
|
116
|
-
if n < 1 {
|
|
117
|
-
return nil, fmt.Errorf("@ttsc/lint: format.tabWidth must be a positive integer; got %d", n)
|
|
118
|
-
}
|
|
119
|
-
pwOpts["tabWidth"] = n
|
|
120
|
-
}
|
|
121
|
-
if v, ok := raw["useTabs"]; ok {
|
|
122
|
-
b, err := asBool("format.useTabs", v)
|
|
123
|
-
if err != nil {
|
|
124
|
-
return nil, err
|
|
125
|
-
}
|
|
126
|
-
pwOpts["useTabs"] = b
|
|
127
|
-
}
|
|
128
|
-
if v, ok := raw["endOfLine"]; ok {
|
|
129
|
-
s, err := asString("format.endOfLine", v)
|
|
130
|
-
if err != nil {
|
|
131
|
-
return nil, err
|
|
132
|
-
}
|
|
133
|
-
if s != "lf" && s != "crlf" {
|
|
134
|
-
return nil, fmt.Errorf("@ttsc/lint: format.endOfLine must be \"lf\" or \"crlf\"; got %q", s)
|
|
135
|
-
}
|
|
136
|
-
pwOpts["endOfLine"] = s
|
|
137
|
-
}
|
|
138
182
|
out["format/print-width"] = ruleEntry(pwOpts)
|
|
139
183
|
|
|
140
|
-
//
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
184
|
+
// formatClauseJoin, always on. Reuses the printWidth/tabWidth/useTabs
|
|
185
|
+
// budget so it only joins a single-statement clause body back onto its
|
|
186
|
+
// header when the joined line fits. A distinct map instance so it does
|
|
187
|
+
// not alias the print-width blob.
|
|
188
|
+
out["format/clause-join"] = ruleEntry(cloneStringAnyMap(pwOpts))
|
|
189
|
+
|
|
190
|
+
// formatDeclarationHeader, always on. Reflows a class/interface header
|
|
191
|
+
// (type parameters + heritage clauses) to Prettier's break shapes;
|
|
192
|
+
// needs the same printWidth/tabWidth/useTabs budget.
|
|
193
|
+
out["format/declaration-header"] = ruleEntry(cloneStringAnyMap(pwOpts))
|
|
194
|
+
|
|
195
|
+
// formatTernaryNullishParens, always on, no options: wraps a `??`
|
|
196
|
+
// operand of a conditional expression in parentheses (Prettier 3).
|
|
197
|
+
out["format/ternary-nullish-parens"] = ruleEntry(map[string]any{})
|
|
198
|
+
|
|
199
|
+
// formatStatementSplit + formatIndent, always on, Prettier-style.
|
|
200
|
+
// Both reuse the indentation/EOL settings to synthesize line breaks
|
|
201
|
+
// and indent strings. Only the keys the user actually set are mirrored
|
|
202
|
+
// in (same conditional shape as print-width's pwOpts), so defaults are
|
|
203
|
+
// applied rule-side. The two rules share the same option surface
|
|
204
|
+
// collected once into layoutOpts above.
|
|
205
|
+
//
|
|
206
|
+
// Distinct map instances so the two rule entries don't alias one blob.
|
|
207
|
+
out["format/statement-split"] = ruleEntry(cloneStringAnyMap(layoutOpts))
|
|
208
|
+
out["format/indent"] = ruleEntry(cloneStringAnyMap(layoutOpts))
|
|
209
|
+
|
|
210
|
+
// formatParameterProperties, always on. Force-breaks a constructor's
|
|
211
|
+
// parameter list when it declares parameter properties; needs only the
|
|
212
|
+
// indentation settings.
|
|
213
|
+
out["format/parameter-properties"] = ruleEntry(cloneStringAnyMap(layoutOpts))
|
|
214
|
+
|
|
215
|
+
// formatWhitespace, always on. Needs only endOfLine for the final
|
|
216
|
+
// newline; indentation is irrelevant to text hygiene.
|
|
217
|
+
wsOpts := map[string]any{}
|
|
218
|
+
if v, ok := layoutOpts["endOfLine"]; ok {
|
|
219
|
+
wsOpts["endOfLine"] = v
|
|
220
|
+
}
|
|
221
|
+
out["format/whitespace"] = ruleEntry(wsOpts)
|
|
222
|
+
|
|
223
|
+
// formatSortImports, opt-in by `sortImports` (a boolean or options object).
|
|
224
|
+
if v, ok := raw["sortImports"]; ok && v != nil {
|
|
225
|
+
siOpts, enabled, err := expandSortImportsBlock(v)
|
|
144
226
|
if err != nil {
|
|
145
227
|
return nil, err
|
|
146
228
|
}
|
|
147
|
-
if
|
|
148
|
-
|
|
149
|
-
}
|
|
150
|
-
siOpts["importOrder"] = order
|
|
151
|
-
if x, ok := raw["importOrderSeparation"]; ok {
|
|
152
|
-
b, err := asBool("format.importOrderSeparation", x)
|
|
153
|
-
if err != nil {
|
|
154
|
-
return nil, err
|
|
155
|
-
}
|
|
156
|
-
siOpts["importOrderSeparation"] = b
|
|
157
|
-
}
|
|
158
|
-
if x, ok := raw["importOrderSortSpecifiers"]; ok {
|
|
159
|
-
b, err := asBool("format.importOrderSortSpecifiers", x)
|
|
160
|
-
if err != nil {
|
|
161
|
-
return nil, err
|
|
162
|
-
}
|
|
163
|
-
siOpts["importOrderSortSpecifiers"] = b
|
|
164
|
-
}
|
|
165
|
-
if x, ok := raw["importOrderCaseInsensitive"]; ok {
|
|
166
|
-
b, err := asBool("format.importOrderCaseInsensitive", x)
|
|
167
|
-
if err != nil {
|
|
168
|
-
return nil, err
|
|
169
|
-
}
|
|
170
|
-
siOpts["importOrderCaseInsensitive"] = b
|
|
229
|
+
if enabled {
|
|
230
|
+
out["format/sort-imports"] = ruleEntry(siOpts)
|
|
171
231
|
}
|
|
172
|
-
out["format/sort-imports"] = ruleEntry(siOpts)
|
|
173
232
|
}
|
|
174
233
|
|
|
175
|
-
//
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
234
|
+
// formatJsdoc, always-on. `jsDoc: false` opts out; a
|
|
235
|
+
// `{ tagSynonyms, sortTags }` object customizes it. The config key is
|
|
236
|
+
// camelCased (jsDoc) to match the other multi-word keys; the emitted rule id
|
|
237
|
+
// stays `format/jsdoc`.
|
|
238
|
+
//
|
|
239
|
+
// Today the rule only rewrites tag synonyms (@return → @returns, ...); tag
|
|
240
|
+
// sorting, column alignment, and wrapping are on the roadmap. It is on by
|
|
241
|
+
// default so JSDoc tag names normalize without opt-in, matching the rest of
|
|
242
|
+
// the always-on format set.
|
|
243
|
+
jdOpts := map[string]any{}
|
|
244
|
+
jdEnabled := true
|
|
245
|
+
if v, ok := raw["jsDoc"]; ok && v != nil {
|
|
179
246
|
switch j := v.(type) {
|
|
180
247
|
case bool:
|
|
181
|
-
|
|
248
|
+
jdEnabled = j
|
|
182
249
|
case map[string]any:
|
|
183
|
-
enabled = true
|
|
184
250
|
for key, val := range j {
|
|
185
251
|
switch key {
|
|
186
252
|
case "tagSynonyms":
|
|
187
253
|
ts, ok := val.(map[string]any)
|
|
188
254
|
if !ok {
|
|
189
|
-
return nil, fmt.Errorf("@ttsc/lint: format.
|
|
255
|
+
return nil, fmt.Errorf("@ttsc/lint: format.jsDoc.tagSynonyms must be an object, got %T", val)
|
|
190
256
|
}
|
|
191
257
|
// Element values must be strings; surface
|
|
192
258
|
// typos early instead of after a downstream
|
|
193
259
|
// JSON-decode failure.
|
|
194
260
|
for k, v := range ts {
|
|
195
261
|
if _, ok := v.(string); !ok {
|
|
196
|
-
return nil, fmt.Errorf("@ttsc/lint: format.
|
|
262
|
+
return nil, fmt.Errorf("@ttsc/lint: format.jsDoc.tagSynonyms[%q] must be a string, got %T", k, v)
|
|
197
263
|
}
|
|
198
264
|
}
|
|
199
265
|
jdOpts["tagSynonyms"] = ts
|
|
200
266
|
case "sortTags":
|
|
201
|
-
b, err := asBool("format.
|
|
267
|
+
b, err := asBool("format.jsDoc.sortTags", val)
|
|
202
268
|
if err != nil {
|
|
203
269
|
return nil, err
|
|
204
270
|
}
|
|
205
271
|
jdOpts["sortTags"] = b
|
|
206
272
|
default:
|
|
207
|
-
return nil, fmt.Errorf("@ttsc/lint: format.
|
|
273
|
+
return nil, fmt.Errorf("@ttsc/lint: format.jsDoc unknown key %q (allowed: tagSynonyms, sortTags)", key)
|
|
208
274
|
}
|
|
209
275
|
}
|
|
210
276
|
default:
|
|
211
|
-
return nil, fmt.Errorf("@ttsc/lint: format.
|
|
212
|
-
}
|
|
213
|
-
if enabled {
|
|
214
|
-
out["format/jsdoc"] = ruleEntry(jdOpts)
|
|
277
|
+
return nil, fmt.Errorf("@ttsc/lint: format.jsDoc must be a boolean or object, got %T", v)
|
|
215
278
|
}
|
|
216
279
|
}
|
|
280
|
+
if jdEnabled {
|
|
281
|
+
out["format/jsdoc"] = ruleEntry(jdOpts)
|
|
282
|
+
}
|
|
217
283
|
|
|
218
284
|
return out, nil
|
|
219
285
|
}
|
|
220
286
|
|
|
287
|
+
// expandSortImportsBlock translates the `format.sortImports` value (a boolean
|
|
288
|
+
// or an options object) into the rule's option map. The bool reports whether
|
|
289
|
+
// the rule is enabled: `true` and any object enable it, `false` keeps it off.
|
|
290
|
+
func expandSortImportsBlock(v any) (map[string]any, bool, error) {
|
|
291
|
+
switch sv := v.(type) {
|
|
292
|
+
case bool:
|
|
293
|
+
return map[string]any{}, sv, nil
|
|
294
|
+
case map[string]any:
|
|
295
|
+
opts := map[string]any{}
|
|
296
|
+
for key, val := range sv {
|
|
297
|
+
switch key {
|
|
298
|
+
case "order":
|
|
299
|
+
order, err := asStringSlice("format.sortImports.order", val)
|
|
300
|
+
if err != nil {
|
|
301
|
+
return nil, false, err
|
|
302
|
+
}
|
|
303
|
+
if len(order) == 0 {
|
|
304
|
+
return nil, false, fmt.Errorf("@ttsc/lint: format.sortImports.order must contain at least one entry; omit it to use the default order")
|
|
305
|
+
}
|
|
306
|
+
opts["order"] = order
|
|
307
|
+
case "caseSensitive":
|
|
308
|
+
b, err := asBool("format.sortImports.caseSensitive", val)
|
|
309
|
+
if err != nil {
|
|
310
|
+
return nil, false, err
|
|
311
|
+
}
|
|
312
|
+
opts["caseSensitive"] = b
|
|
313
|
+
case "combineTypeAndValue":
|
|
314
|
+
b, err := asBool("format.sortImports.combineTypeAndValue", val)
|
|
315
|
+
if err != nil {
|
|
316
|
+
return nil, false, err
|
|
317
|
+
}
|
|
318
|
+
opts["combineTypeAndValue"] = b
|
|
319
|
+
default:
|
|
320
|
+
return nil, false, fmt.Errorf("@ttsc/lint: format.sortImports unknown key %q (allowed: order, caseSensitive, combineTypeAndValue)", key)
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
return opts, true, nil
|
|
324
|
+
default:
|
|
325
|
+
return nil, false, fmt.Errorf("@ttsc/lint: format.sortImports must be a boolean or object, got %T", v)
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
|
|
221
329
|
// formatBlockSeverity extracts the optional `severity` field from a format
|
|
222
330
|
// block. Defaults to SeverityOff so that format rules never produce check/build
|
|
223
331
|
// diagnostics unless the user explicitly opts in. SeverityOff still allows
|
|
@@ -234,12 +342,20 @@ func formatBlockSeverity(raw map[string]any) (Severity, error) {
|
|
|
234
342
|
return severity, nil
|
|
235
343
|
}
|
|
236
344
|
|
|
345
|
+
// isFormatRuleName reports whether `name` is a formatter rule id. Such
|
|
346
|
+
// rules are configured exclusively through the `format` block; a `format/*`
|
|
347
|
+
// key in the user's `rules` map is dropped before the merge, so the config
|
|
348
|
+
// layer never carries a formatter setting in two places.
|
|
349
|
+
func isFormatRuleName(name string) bool {
|
|
350
|
+
return strings.HasPrefix(name, "format/")
|
|
351
|
+
}
|
|
352
|
+
|
|
237
353
|
// mergeRuleMaps overlays `overrides` on `base` and returns the merged
|
|
238
354
|
// map. Identical keys in `overrides` replace the entire entry from
|
|
239
|
-
// `base`; option objects are NOT deep-merged
|
|
240
|
-
//
|
|
241
|
-
//
|
|
242
|
-
//
|
|
355
|
+
// `base`; option objects are NOT deep-merged. `overrides` (the user's
|
|
356
|
+
// `rules` map) never contains a `format/*` key, those are dropped before
|
|
357
|
+
// the merge, so the merge only ever layers lint-rule severities on top of
|
|
358
|
+
// the format block's expanded entries.
|
|
243
359
|
func mergeRuleMaps(base, overrides map[string]any) map[string]any {
|
|
244
360
|
out := make(map[string]any, len(base)+len(overrides))
|
|
245
361
|
for k, v := range base {
|
|
@@ -251,6 +367,56 @@ func mergeRuleMaps(base, overrides map[string]any) map[string]any {
|
|
|
251
367
|
return out
|
|
252
368
|
}
|
|
253
369
|
|
|
370
|
+
// cloneStringAnyMap returns a shallow copy of `m`. expandFormatBlock uses
|
|
371
|
+
// it so `format/statement-split` and `format/indent` each receive their
|
|
372
|
+
// own options blob rather than aliasing one shared map, a later mutation
|
|
373
|
+
// or marshal of one entry then cannot leak into the other.
|
|
374
|
+
func cloneStringAnyMap(m map[string]any) map[string]any {
|
|
375
|
+
out := make(map[string]any, len(m))
|
|
376
|
+
for k, v := range m {
|
|
377
|
+
out[k] = v
|
|
378
|
+
}
|
|
379
|
+
return out
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
// collectLayoutOpts parses the shared tabWidth/useTabs/endOfLine layout
|
|
383
|
+
// fields from a format block once. Only keys the user actually set are
|
|
384
|
+
// emitted, so rule-side defaults still apply for absent fields. Both the
|
|
385
|
+
// print-width blob (which adds trailingComma + printWidth) and the
|
|
386
|
+
// statement-split/indent/parameter-properties entries derive from this
|
|
387
|
+
// single source so their parse-and-validate logic stays in one place.
|
|
388
|
+
func collectLayoutOpts(raw map[string]any) (map[string]any, error) {
|
|
389
|
+
layoutOpts := map[string]any{}
|
|
390
|
+
if v, ok := raw["tabWidth"]; ok {
|
|
391
|
+
n, err := asInt("format.tabWidth", v)
|
|
392
|
+
if err != nil {
|
|
393
|
+
return nil, err
|
|
394
|
+
}
|
|
395
|
+
if n < 1 {
|
|
396
|
+
return nil, fmt.Errorf("@ttsc/lint: format.tabWidth must be a positive integer; got %d", n)
|
|
397
|
+
}
|
|
398
|
+
layoutOpts["tabWidth"] = n
|
|
399
|
+
}
|
|
400
|
+
if v, ok := raw["useTabs"]; ok {
|
|
401
|
+
b, err := asBool("format.useTabs", v)
|
|
402
|
+
if err != nil {
|
|
403
|
+
return nil, err
|
|
404
|
+
}
|
|
405
|
+
layoutOpts["useTabs"] = b
|
|
406
|
+
}
|
|
407
|
+
if v, ok := raw["endOfLine"]; ok {
|
|
408
|
+
s, err := asString("format.endOfLine", v)
|
|
409
|
+
if err != nil {
|
|
410
|
+
return nil, err
|
|
411
|
+
}
|
|
412
|
+
if s != "lf" && s != "crlf" {
|
|
413
|
+
return nil, fmt.Errorf("@ttsc/lint: format.endOfLine must be \"lf\" or \"crlf\"; got %q", s)
|
|
414
|
+
}
|
|
415
|
+
layoutOpts["endOfLine"] = s
|
|
416
|
+
}
|
|
417
|
+
return layoutOpts, nil
|
|
418
|
+
}
|
|
419
|
+
|
|
254
420
|
// asBool coerces a raw config value to a bool, returning a typed error on
|
|
255
421
|
// failure. Used by expandFormatBlock to validate boolean format fields.
|
|
256
422
|
func asBool(field string, v any) (bool, error) {
|
|
@@ -314,26 +480,26 @@ func asStringSlice(field string, v any) ([]string, error) {
|
|
|
314
480
|
|
|
315
481
|
// rejectUnknownFormatKeys surfaces typos in top-level format-block
|
|
316
482
|
// keys at the boundary rather than silently ignoring them. The
|
|
317
|
-
// key set mirrors `
|
|
483
|
+
// key set mirrors `ITtscLintFormat` exactly.
|
|
318
484
|
func rejectUnknownFormatKeys(raw map[string]any) error {
|
|
319
485
|
allowed := map[string]struct{}{
|
|
320
|
-
"severity":
|
|
321
|
-
"semi":
|
|
322
|
-
"singleQuote":
|
|
323
|
-
"
|
|
324
|
-
"
|
|
325
|
-
"
|
|
326
|
-
"
|
|
327
|
-
"
|
|
328
|
-
"
|
|
329
|
-
"
|
|
330
|
-
"
|
|
331
|
-
"
|
|
332
|
-
"
|
|
486
|
+
"severity": {},
|
|
487
|
+
"semi": {},
|
|
488
|
+
"singleQuote": {},
|
|
489
|
+
"arrowParens": {},
|
|
490
|
+
"bracketSpacing": {},
|
|
491
|
+
"quoteProps": {},
|
|
492
|
+
"trailingComma": {},
|
|
493
|
+
"printWidth": {},
|
|
494
|
+
"tabWidth": {},
|
|
495
|
+
"useTabs": {},
|
|
496
|
+
"endOfLine": {},
|
|
497
|
+
"sortImports": {},
|
|
498
|
+
"jsDoc": {},
|
|
333
499
|
}
|
|
334
500
|
for key := range raw {
|
|
335
501
|
if _, ok := allowed[key]; !ok {
|
|
336
|
-
return fmt.Errorf("@ttsc/lint: format unknown key %q; see
|
|
502
|
+
return fmt.Errorf("@ttsc/lint: format unknown key %q; see ITtscLintFormat for the allowed surface", key)
|
|
337
503
|
}
|
|
338
504
|
}
|
|
339
505
|
return nil
|