@sun-asterisk/sunlint 1.3.32 → 1.3.34
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 +47 -0
- package/config/released-rules.json +62 -0
- package/config/rules/enhanced-rules-registry.json +2315 -1354
- package/core/adapters/dart-analyzer.js +658 -0
- package/core/adapters/index.js +102 -0
- package/core/adapters/sunlint-rule-adapter.js +0 -2
- package/core/adapters/typescript-analyzer.js +277 -0
- package/core/analysis-orchestrator.js +168 -40
- package/core/architecture-integration.js +220 -0
- package/core/cli-action-handler.js +72 -24
- package/core/cli-program.js +13 -1
- package/core/config-merger.js +24 -14
- package/core/constants/defaults.js +1 -2
- package/core/github-annotate-service.js +141 -89
- package/core/github-step-summary-generator.js +8 -8
- package/core/interfaces/language-analyzer.interface.js +393 -0
- package/core/output-service.js +102 -38
- package/core/rule-selection-service.js +77 -27
- package/core/scoring-service.js +65 -20
- package/core/semantic-engine-manager.js +375 -0
- package/core/semantic-engine.js +4 -57
- package/core/unified-rule-registry.js +52 -11
- package/core/upload-service.js +43 -9
- package/docs/DART_RULE_EXECUTION_FLOW.md +745 -0
- package/docs/DART_SUPPORT_IMPLEMENTATION.md +245 -0
- package/docs/SUNLINT_ARCHITECTURE.md +692 -0
- package/docs/skills/CREATE_DART_RULE.md +909 -0
- package/engines/eslint-engine.js +2 -8
- package/engines/heuristic-engine.js +234 -38
- package/package.json +6 -5
- package/rules/common/C002_no_duplicate_code/config.json +12 -20
- package/rules/common/C002_no_duplicate_code/dart/analyzer.js +53 -0
- package/rules/common/C002_no_duplicate_code/index.js +93 -0
- package/rules/common/C003_no_vague_abbreviations/config.json +1 -1
- package/rules/common/C003_no_vague_abbreviations/dart/analyzer.js +54 -0
- package/rules/common/C003_no_vague_abbreviations/index.js +93 -0
- package/rules/common/C006_function_naming/dart/analyzer.js +40 -0
- package/rules/common/C006_function_naming/index.js +86 -0
- package/rules/common/C008_variable_declaration_locality/dart/analyzer.js +32 -0
- package/rules/common/C008_variable_declaration_locality/index.js +86 -0
- package/rules/common/C010_limit_block_nesting/dart/analyzer.js +32 -0
- package/rules/common/C010_limit_block_nesting/index.js +86 -0
- package/rules/common/C012_command_query_separation/config.json +61 -0
- package/rules/common/C012_command_query_separation/dart/analyzer.js +32 -0
- package/rules/common/C012_command_query_separation/index.js +86 -0
- package/rules/common/C013_no_dead_code/dart/analyzer.js +32 -0
- package/rules/common/C013_no_dead_code/index.js +86 -0
- package/rules/common/C014_dependency_injection/dart/analyzer.js +32 -0
- package/rules/common/C014_dependency_injection/index.js +86 -0
- package/rules/common/C017_constructor_logic/dart/analyzer.js +32 -0
- package/rules/common/C017_constructor_logic/index.js +86 -0
- package/rules/common/C018_no_throw_generic_error/dart/analyzer.js +32 -0
- package/rules/common/C018_no_throw_generic_error/index.js +86 -0
- package/rules/common/C019_log_level_usage/dart/analyzer.js +32 -0
- package/rules/common/C019_log_level_usage/index.js +86 -0
- package/rules/common/C019_log_level_usage/{ts-morph-analyzer.js → typescript/ts-morph-analyzer.js} +0 -1
- package/rules/common/C020_unused_imports/dart/analyzer.js +32 -0
- package/rules/common/C020_unused_imports/index.js +86 -0
- package/rules/common/C020_unused_imports/{ts-morph-analyzer.js → typescript/ts-morph-analyzer.js} +0 -1
- package/rules/common/C021_import_organization/config.json +29 -9
- package/rules/common/C021_import_organization/dart/analyzer.js +40 -0
- package/rules/common/C021_import_organization/index.js +83 -0
- package/rules/common/C021_import_organization/{ts-morph-analyzer.js → typescript/ts-morph-analyzer.js} +0 -1
- package/rules/common/C023_no_duplicate_variable/config.json +7 -2
- package/rules/common/C023_no_duplicate_variable/dart/analyzer.js +40 -0
- package/rules/common/C023_no_duplicate_variable/index.js +83 -0
- package/rules/common/C024_no_scatter_hardcoded_constants/config.json +7 -2
- package/rules/common/C024_no_scatter_hardcoded_constants/dart/analyzer.js +40 -0
- package/rules/common/C024_no_scatter_hardcoded_constants/index.js +83 -0
- package/rules/common/C024_no_scatter_hardcoded_constants/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +19 -1
- package/rules/common/C029_catch_block_logging/config.json +15 -5
- package/rules/common/C029_catch_block_logging/dart/analyzer.js +40 -0
- package/rules/common/C029_catch_block_logging/index.js +83 -0
- package/rules/common/C030_use_custom_error_classes/config.json +28 -0
- package/rules/common/C030_use_custom_error_classes/dart/analyzer.js +40 -0
- package/rules/common/C030_use_custom_error_classes/index.js +83 -0
- package/rules/common/C031_validation_separation/config.json +28 -0
- package/rules/common/C031_validation_separation/dart/analyzer.js +40 -0
- package/rules/common/C031_validation_separation/index.js +83 -0
- package/rules/common/C033_separate_service_repository/config.json +8 -3
- package/rules/common/C033_separate_service_repository/dart/analyzer.js +40 -0
- package/rules/common/C033_separate_service_repository/index.js +83 -0
- package/rules/common/C035_error_logging_context/config.json +34 -12
- package/rules/common/C035_error_logging_context/dart/analyzer.js +40 -0
- package/rules/common/C035_error_logging_context/index.js +83 -0
- package/rules/common/C040_centralized_validation/config.json +37 -8
- package/rules/common/C040_centralized_validation/dart/analyzer.js +40 -0
- package/rules/common/C040_centralized_validation/index.js +83 -0
- package/rules/common/C041_no_sensitive_hardcode/config.json +7 -2
- package/rules/common/C041_no_sensitive_hardcode/dart/analyzer.js +40 -0
- package/rules/common/C041_no_sensitive_hardcode/index.js +83 -0
- package/rules/common/C042_boolean_name_prefix/config.json +28 -0
- package/rules/common/C042_boolean_name_prefix/dart/analyzer.js +40 -0
- package/rules/common/C042_boolean_name_prefix/index.js +83 -0
- package/rules/common/C043_no_console_or_print/config.json +28 -0
- package/rules/common/C043_no_console_or_print/dart/analyzer.js +40 -0
- package/rules/common/C043_no_console_or_print/index.js +83 -0
- package/rules/common/C047_no_duplicate_retry_logic/config.json +28 -0
- package/rules/common/C047_no_duplicate_retry_logic/dart/analyzer.js +40 -0
- package/rules/common/C047_no_duplicate_retry_logic/index.js +83 -0
- package/rules/common/C048_no_bypass_architectural_layers/config.json +7 -2
- package/rules/common/C048_no_bypass_architectural_layers/dart/analyzer.js +40 -0
- package/rules/common/C048_no_bypass_architectural_layers/index.js +83 -0
- package/rules/common/C052_parsing_or_data_transformation/config.json +7 -2
- package/rules/common/C052_parsing_or_data_transformation/dart/analyzer.js +40 -0
- package/rules/common/C052_parsing_or_data_transformation/index.js +83 -0
- package/rules/common/C060_no_override_superclass/config.json +7 -2
- package/rules/common/C060_no_override_superclass/dart/analyzer.js +40 -0
- package/rules/common/C060_no_override_superclass/index.js +83 -0
- package/rules/common/C065_one_behavior_per_test/config.json +187 -28
- package/rules/common/C065_one_behavior_per_test/dart/analyzer.js +40 -0
- package/rules/common/C065_one_behavior_per_test/index.js +83 -0
- package/rules/common/C067_no_hardcoded_config/config.json +18 -4
- package/rules/common/C067_no_hardcoded_config/dart/analyzer.js +40 -0
- package/rules/common/C067_no_hardcoded_config/index.js +83 -0
- package/rules/common/C070_no_real_time_tests/config.json +41 -12
- package/rules/common/C070_no_real_time_tests/dart/analyzer.js +40 -0
- package/rules/common/C070_no_real_time_tests/index.js +83 -0
- package/rules/common/C072_single_test_behavior/config.json +28 -0
- package/rules/common/C072_single_test_behavior/dart/analyzer.js +40 -0
- package/rules/common/C072_single_test_behavior/index.js +83 -0
- package/rules/common/C073_validate_required_config_on_startup/config.json +93 -18
- package/rules/common/C073_validate_required_config_on_startup/dart/analyzer.js +40 -0
- package/rules/common/C073_validate_required_config_on_startup/index.js +83 -0
- package/rules/common/C073_validate_required_config_on_startup/{analyzer.js → typescript/analyzer.js} +0 -1
- package/rules/common/C075_explicit_return_types/config.json +28 -0
- package/rules/common/C075_explicit_return_types/dart/analyzer.js +40 -0
- package/rules/common/C075_explicit_return_types/index.js +83 -0
- package/rules/common/C076_explicit_function_types/config.json +18 -4
- package/rules/common/C076_explicit_function_types/dart/analyzer.js +40 -0
- package/rules/common/C076_explicit_function_types/index.js +83 -0
- package/rules/index.js +26 -6
- package/rules/security/S003_open_redirect_protection/config.json +11 -53
- package/rules/security/S003_open_redirect_protection/dart/analyzer.js +43 -0
- package/rules/security/S003_open_redirect_protection/index.js +94 -0
- package/rules/security/S003_open_redirect_protection/typescript/analyzer.js +105 -0
- package/rules/security/S003_open_redirect_protection/{symbol-based-analyzer.js → typescript/semantic-analyzer.js} +1 -1
- package/rules/security/S004_sensitive_data_logging/config.json +1 -1
- package/rules/security/S004_sensitive_data_logging/dart/analyzer.js +58 -0
- package/rules/security/S004_sensitive_data_logging/index.js +93 -0
- package/rules/security/S005_no_origin_auth/dart/analyzer.js +30 -0
- package/rules/security/S005_no_origin_auth/index.js +83 -0
- package/rules/security/S005_no_origin_auth/{analyzer.js → typescript/analyzer.js} +1 -0
- package/rules/security/S006_no_plaintext_recovery_codes/dart/analyzer.js +30 -0
- package/rules/security/S006_no_plaintext_recovery_codes/index.js +83 -0
- package/rules/security/S007_no_plaintext_otp/dart/analyzer.js +30 -0
- package/rules/security/S007_no_plaintext_otp/index.js +83 -0
- package/rules/security/S009_no_insecure_encryption/dart/analyzer.js +30 -0
- package/rules/security/S009_no_insecure_encryption/index.js +83 -0
- package/rules/security/S010_no_insecure_encryption/dart/analyzer.js +30 -0
- package/rules/security/S010_no_insecure_encryption/index.js +83 -0
- package/rules/security/S011_secure_guid_generation/dart/analyzer.js +30 -0
- package/rules/security/S011_secure_guid_generation/index.js +83 -0
- package/rules/security/S012_hardcoded_secrets/dart/analyzer.js +30 -0
- package/rules/security/S012_hardcoded_secrets/index.js +83 -0
- package/rules/security/S012_hardcoded_secrets/typescript/config.json +75 -0
- package/rules/security/S013_tls_enforcement/dart/analyzer.js +30 -0
- package/rules/security/S013_tls_enforcement/index.js +83 -0
- package/rules/security/S014_tls_version_enforcement/dart/analyzer.js +30 -0
- package/rules/security/S014_tls_version_enforcement/index.js +83 -0
- package/rules/security/S015_insecure_tls_certificate/config.json +41 -0
- package/rules/security/S015_insecure_tls_certificate/dart/analyzer.js +19 -0
- package/rules/security/S015_insecure_tls_certificate/index.js +83 -0
- package/rules/security/S016_no_sensitive_querystring/dart/analyzer.js +30 -0
- package/rules/security/S016_no_sensitive_querystring/index.js +83 -0
- package/rules/security/S017_use_parameterized_queries/dart/analyzer.js +30 -0
- package/rules/security/S017_use_parameterized_queries/index.js +83 -0
- package/rules/security/S019_smtp_injection_protection/dart/analyzer.js +30 -0
- package/rules/security/S019_smtp_injection_protection/index.js +83 -0
- package/rules/security/S020_no_eval_dynamic_code/dart/analyzer.js +30 -0
- package/rules/security/S020_no_eval_dynamic_code/index.js +83 -0
- package/rules/security/S022_escape_output_context/dart/analyzer.js +30 -0
- package/rules/security/S022_escape_output_context/index.js +83 -0
- package/rules/security/S023_no_json_injection/dart/analyzer.js +30 -0
- package/rules/security/S023_no_json_injection/index.js +83 -0
- package/rules/security/S024_xpath_xxe_protection/dart/analyzer.js +30 -0
- package/rules/security/S024_xpath_xxe_protection/index.js +83 -0
- package/rules/security/S025_server_side_validation/dart/analyzer.js +30 -0
- package/rules/security/S025_server_side_validation/index.js +83 -0
- package/rules/security/S026_json_schema_validation/dart/analyzer.js +30 -0
- package/rules/security/S026_json_schema_validation/index.js +83 -0
- package/rules/security/S027_no_hardcoded_secrets/dart/analyzer.js +30 -0
- package/rules/security/S027_no_hardcoded_secrets/index.js +83 -0
- package/rules/security/S028_file_upload_size_limits/dart/analyzer.js +30 -0
- package/rules/security/S028_file_upload_size_limits/index.js +83 -0
- package/rules/security/S029_csrf_protection/dart/analyzer.js +30 -0
- package/rules/security/S029_csrf_protection/index.js +83 -0
- package/rules/security/S030_directory_browsing_protection/dart/analyzer.js +30 -0
- package/rules/security/S030_directory_browsing_protection/index.js +83 -0
- package/rules/security/S031_secure_session_cookies/dart/analyzer.js +30 -0
- package/rules/security/S031_secure_session_cookies/index.js +83 -0
- package/rules/security/S032_httponly_session_cookies/dart/analyzer.js +30 -0
- package/rules/security/S032_httponly_session_cookies/index.js +83 -0
- package/rules/security/S033_samesite_session_cookies/dart/analyzer.js +30 -0
- package/rules/security/S033_samesite_session_cookies/index.js +83 -0
- package/rules/security/S034_host_prefix_session_cookies/dart/analyzer.js +30 -0
- package/rules/security/S034_host_prefix_session_cookies/index.js +83 -0
- package/rules/security/S035_path_session_cookies/dart/analyzer.js +30 -0
- package/rules/security/S035_path_session_cookies/index.js +83 -0
- package/rules/security/S036_lfi_rfi_protection/dart/analyzer.js +30 -0
- package/rules/security/S036_lfi_rfi_protection/index.js +83 -0
- package/rules/security/S037_cache_headers/dart/analyzer.js +30 -0
- package/rules/security/S037_cache_headers/index.js +83 -0
- package/rules/security/S038_no_version_headers/dart/analyzer.js +30 -0
- package/rules/security/S038_no_version_headers/index.js +83 -0
- package/rules/security/S039_no_session_tokens_in_url/dart/analyzer.js +30 -0
- package/rules/security/S039_no_session_tokens_in_url/index.js +83 -0
- package/rules/security/S040_session_fixation_protection/dart/analyzer.js +30 -0
- package/rules/security/S040_session_fixation_protection/index.js +83 -0
- package/rules/security/S041_session_token_invalidation/dart/analyzer.js +30 -0
- package/rules/security/S041_session_token_invalidation/index.js +83 -0
- package/rules/security/S042_require_re_authentication_for_long_lived/dart/analyzer.js +30 -0
- package/rules/security/S042_require_re_authentication_for_long_lived/index.js +83 -0
- package/rules/security/S043_password_changes_invalidate_all_sessions/dart/analyzer.js +30 -0
- package/rules/security/S043_password_changes_invalidate_all_sessions/index.js +83 -0
- package/rules/security/S044_re_authentication_required/dart/analyzer.js +30 -0
- package/rules/security/S044_re_authentication_required/index.js +83 -0
- package/rules/security/S045_brute_force_protection/dart/analyzer.js +30 -0
- package/rules/security/S045_brute_force_protection/index.js +83 -0
- package/rules/security/S048_no_current_password_in_reset/dart/analyzer.js +30 -0
- package/rules/security/S048_no_current_password_in_reset/index.js +83 -0
- package/rules/security/S049_short_validity_tokens/dart/analyzer.js +30 -0
- package/rules/security/S049_short_validity_tokens/index.js +83 -0
- package/rules/security/S049_short_validity_tokens/typescript/config.json +124 -0
- package/rules/security/S051_password_length_policy/dart/analyzer.js +30 -0
- package/rules/security/S051_password_length_policy/index.js +83 -0
- package/rules/security/S051_password_length_policy/typescript/config.json +83 -0
- package/rules/security/S052_weak_otp_entropy/dart/analyzer.js +30 -0
- package/rules/security/S052_weak_otp_entropy/index.js +83 -0
- package/rules/security/S052_weak_otp_entropy/typescript/config.json +57 -0
- package/rules/security/S054_no_default_accounts/dart/analyzer.js +30 -0
- package/rules/security/S054_no_default_accounts/index.js +83 -0
- package/rules/security/S054_no_default_accounts/typescript/config.json +101 -0
- package/rules/security/S055_content_type_validation/dart/analyzer.js +30 -0
- package/rules/security/S055_content_type_validation/index.js +83 -0
- package/rules/security/S056_log_injection_protection/dart/analyzer.js +30 -0
- package/rules/security/S056_log_injection_protection/index.js +83 -0
- package/rules/security/S057_utc_logging/dart/analyzer.js +30 -0
- package/rules/security/S057_utc_logging/index.js +83 -0
- package/rules/security/S057_utc_logging/typescript/config.json +105 -0
- package/rules/security/S058_no_ssrf/dart/analyzer.js +30 -0
- package/rules/security/S058_no_ssrf/index.js +83 -0
- package/rules/security/S058_no_ssrf/{analyzer.js → typescript/analyzer.js} +0 -1
- package/rules/security/S058_no_ssrf/typescript/config.json +125 -0
- package/scripts/build-release.sh +12 -0
- package/scripts/copy-arch-detect.js +78 -0
- package/rules/common/C002_no_duplicate_code/test-cases/api-handlers.ts +0 -64
- package/rules/common/C002_no_duplicate_code/test-cases/data-processor.ts +0 -46
- package/rules/common/C002_no_duplicate_code/test-cases/good-example.tsx +0 -40
- package/rules/common/C002_no_duplicate_code/test-cases/product-service.ts +0 -57
- package/rules/common/C002_no_duplicate_code/test-cases/user-service.ts +0 -49
- package/rules/common/C067_no_hardcoded_config/symbol-based-analyzer.js.backup +0 -3853
- package/rules/security/S003_open_redirect_protection/analyzer.js +0 -135
- /package/rules/common/C002_no_duplicate_code/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C003_no_vague_abbreviations/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C006_function_naming/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/{C008 → C008_variable_declaration_locality}/config.json +0 -0
- /package/rules/common/{C008 → C008_variable_declaration_locality/typescript}/analyzer.js +0 -0
- /package/rules/common/{C008 → C008_variable_declaration_locality/typescript}/ts-morph-analyzer.js +0 -0
- /package/rules/common/C010_limit_block_nesting/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C010_limit_block_nesting/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
- /package/rules/common/C010_limit_block_nesting/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/common/C012_command_query_separation/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C012_command_query_separation/{ast-analyzer.js → typescript/ast-analyzer.js} +0 -0
- /package/rules/common/C013_no_dead_code/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C013_no_dead_code/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
- /package/rules/common/C013_no_dead_code/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/common/C014_dependency_injection/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C014_dependency_injection/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/common/C017_constructor_logic/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C017_constructor_logic/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/common/C018_no_throw_generic_error/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C018_no_throw_generic_error/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
- /package/rules/common/C018_no_throw_generic_error/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/common/C019_log_level_usage/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C019_log_level_usage/{pattern-analyzer.js → typescript/pattern-analyzer.js} +0 -0
- /package/rules/common/C019_log_level_usage/{system-log-analyzer.js → typescript/system-log-analyzer.js} +0 -0
- /package/rules/common/C020_unused_imports/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C021_import_organization/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C023_no_duplicate_variable/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C023_no_duplicate_variable/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/common/C024_no_scatter_hardcoded_constants/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C029_catch_block_logging/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C030_use_custom_error_classes/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C031_validation_separation/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C033_separate_service_repository/{README.md → typescript/README.md} +0 -0
- /package/rules/common/C033_separate_service_repository/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C033_separate_service_repository/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
- /package/rules/common/C033_separate_service_repository/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/common/C035_error_logging_context/{STRATEGY.md → typescript/STRATEGY.md} +0 -0
- /package/rules/common/C035_error_logging_context/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C035_error_logging_context/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
- /package/rules/common/C035_error_logging_context/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/common/C040_centralized_validation/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C040_centralized_validation/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
- /package/rules/common/C040_centralized_validation/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/common/C041_no_sensitive_hardcode/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C041_no_sensitive_hardcode/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/common/C042_boolean_name_prefix/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C043_no_console_or_print/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C047_no_duplicate_retry_logic/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C047_no_duplicate_retry_logic/{c047-semantic-rule.js → typescript/c047-semantic-rule.js} +0 -0
- /package/rules/common/C047_no_duplicate_retry_logic/{symbol-analyzer-enhanced.js → typescript/symbol-analyzer-enhanced.js} +0 -0
- /package/rules/common/C047_no_duplicate_retry_logic/{symbol-config.json → typescript/symbol-config.json} +0 -0
- /package/rules/common/C048_no_bypass_architectural_layers/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C048_no_bypass_architectural_layers/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/common/C052_parsing_or_data_transformation/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C052_parsing_or_data_transformation/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/common/C060_no_override_superclass/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C060_no_override_superclass/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/common/C065_one_behavior_per_test/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C067_no_hardcoded_config/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C067_no_hardcoded_config/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/common/C070_no_real_time_tests/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C070_no_real_time_tests/{regex-analyzer.js → typescript/regex-analyzer.js} +0 -0
- /package/rules/common/C072_single_test_behavior/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C073_validate_required_config_on_startup/{README.md → typescript/README.md} +0 -0
- /package/rules/common/C073_validate_required_config_on_startup/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/common/C075_explicit_return_types/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C076_explicit_function_types/{README.md → typescript/README.md} +0 -0
- /package/rules/common/C076_explicit_function_types/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/common/C076_explicit_function_types/{semantic-analyzer.js → typescript/semantic-analyzer.js} +0 -0
- /package/rules/security/S003_open_redirect_protection/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S004_sensitive_data_logging/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S004_sensitive_data_logging/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/security/S005_no_origin_auth/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S005_no_origin_auth/{ast-analyzer.js → typescript/ast-analyzer.js} +0 -0
- /package/rules/security/S005_no_origin_auth/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/security/S006_no_plaintext_recovery_codes/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S006_no_plaintext_recovery_codes/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S006_no_plaintext_recovery_codes/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/security/S007_no_plaintext_otp/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S007_no_plaintext_otp/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S007_no_plaintext_otp/{semantic-analyzer.js → typescript/semantic-analyzer.js} +0 -0
- /package/rules/security/S007_no_plaintext_otp/{semantic-config.json → typescript/semantic-config.json} +0 -0
- /package/rules/security/S007_no_plaintext_otp/{semantic-wrapper.js → typescript/semantic-wrapper.js} +0 -0
- /package/rules/security/S009_no_insecure_encryption/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S009_no_insecure_encryption/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S010_no_insecure_encryption/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S010_no_insecure_encryption/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S011_secure_guid_generation/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S011_secure_guid_generation/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S011_secure_guid_generation/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/security/S012_hardcoded_secrets/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S012_hardcoded_secrets/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/security/S013_tls_enforcement/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S013_tls_enforcement/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S013_tls_enforcement/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/security/S014_tls_version_enforcement/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S014_tls_version_enforcement/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S014_tls_version_enforcement/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/security/S015_insecure_tls_certificate/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S015_insecure_tls_certificate/{ast-analyzer.js → typescript/ast-analyzer.js} +0 -0
- /package/rules/security/S016_no_sensitive_querystring/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S016_no_sensitive_querystring/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
- /package/rules/security/S016_no_sensitive_querystring/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/security/S017_use_parameterized_queries/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S017_use_parameterized_queries/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S017_use_parameterized_queries/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/security/S019_smtp_injection_protection/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S019_smtp_injection_protection/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/security/S020_no_eval_dynamic_code/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S020_no_eval_dynamic_code/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S020_no_eval_dynamic_code/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/security/S022_escape_output_context/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S022_escape_output_context/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S023_no_json_injection/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S023_no_json_injection/{ast-analyzer.js → typescript/ast-analyzer.js} +0 -0
- /package/rules/security/S024_xpath_xxe_protection/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S024_xpath_xxe_protection/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
- /package/rules/security/S024_xpath_xxe_protection/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/security/S025_server_side_validation/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S025_server_side_validation/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S025_server_side_validation/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
- /package/rules/security/S025_server_side_validation/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/security/S026_json_schema_validation/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S027_no_hardcoded_secrets/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S027_no_hardcoded_secrets/{categories.json → typescript/categories.json} +0 -0
- /package/rules/security/S027_no_hardcoded_secrets/{categorized-analyzer.js → typescript/categorized-analyzer.js} +0 -0
- /package/rules/security/S028_file_upload_size_limits/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S028_file_upload_size_limits/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S028_file_upload_size_limits/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/security/S029_csrf_protection/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S030_directory_browsing_protection/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S030_directory_browsing_protection/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S030_directory_browsing_protection/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
- /package/rules/security/S030_directory_browsing_protection/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/security/S031_secure_session_cookies/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S031_secure_session_cookies/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S031_secure_session_cookies/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/security/S032_httponly_session_cookies/{FRAMEWORK_SUPPORT.md → typescript/FRAMEWORK_SUPPORT.md} +0 -0
- /package/rules/security/S032_httponly_session_cookies/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S032_httponly_session_cookies/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S032_httponly_session_cookies/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
- /package/rules/security/S032_httponly_session_cookies/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/security/S033_samesite_session_cookies/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S033_samesite_session_cookies/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S033_samesite_session_cookies/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
- /package/rules/security/S033_samesite_session_cookies/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/security/S034_host_prefix_session_cookies/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S034_host_prefix_session_cookies/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S034_host_prefix_session_cookies/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
- /package/rules/security/S034_host_prefix_session_cookies/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/security/S035_path_session_cookies/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S035_path_session_cookies/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S035_path_session_cookies/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
- /package/rules/security/S035_path_session_cookies/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/security/S036_lfi_rfi_protection/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S037_cache_headers/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S037_cache_headers/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S037_cache_headers/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
- /package/rules/security/S037_cache_headers/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/security/S038_no_version_headers/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S038_no_version_headers/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S038_no_version_headers/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
- /package/rules/security/S038_no_version_headers/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/security/S039_no_session_tokens_in_url/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S039_no_session_tokens_in_url/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S039_no_session_tokens_in_url/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
- /package/rules/security/S039_no_session_tokens_in_url/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/security/S040_session_fixation_protection/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S041_session_token_invalidation/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S041_session_token_invalidation/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S041_session_token_invalidation/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
- /package/rules/security/S041_session_token_invalidation/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/security/S042_require_re_authentication_for_long_lived/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S042_require_re_authentication_for_long_lived/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S042_require_re_authentication_for_long_lived/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/security/S043_password_changes_invalidate_all_sessions/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S043_password_changes_invalidate_all_sessions/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S043_password_changes_invalidate_all_sessions/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/security/S044_re_authentication_required/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S044_re_authentication_required/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S044_re_authentication_required/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
- /package/rules/security/S044_re_authentication_required/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/security/S045_brute_force_protection/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S045_brute_force_protection/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S045_brute_force_protection/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/security/S048_no_current_password_in_reset/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S048_no_current_password_in_reset/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S049_short_validity_tokens/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S049_short_validity_tokens/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
- /package/rules/security/S049_short_validity_tokens/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/security/S051_password_length_policy/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S052_weak_otp_entropy/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S054_no_default_accounts/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S054_no_default_accounts/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S055_content_type_validation/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S055_content_type_validation/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S055_content_type_validation/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/security/S056_log_injection_protection/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S056_log_injection_protection/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
- /package/rules/security/S056_log_injection_protection/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
- /package/rules/security/S057_utc_logging/{README.md → typescript/README.md} +0 -0
- /package/rules/security/S057_utc_logging/{analyzer.js → typescript/analyzer.js} +0 -0
- /package/rules/security/S058_no_ssrf/{README.md → typescript/README.md} +0 -0
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Semantic Engine Manager
|
|
3
|
+
* Manages multiple language analyzers and provides unified access to symbol tables
|
|
4
|
+
* Following Rule C005: Single responsibility - manage language analyzers
|
|
5
|
+
* Following Rule C006: Verb-noun naming pattern
|
|
6
|
+
* Following Rule C014: Dependency injection - uses language analyzer interface
|
|
7
|
+
*
|
|
8
|
+
* This manager enables multi-language semantic analysis by:
|
|
9
|
+
* 1. Registering language-specific analyzers (TypeScript, Dart, etc.)
|
|
10
|
+
* 2. Routing file analysis to the appropriate analyzer
|
|
11
|
+
* 3. Providing unified access to symbol tables across languages
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
const path = require('path');
|
|
15
|
+
const { getRegistry } = require('./interfaces/language-analyzer.interface');
|
|
16
|
+
|
|
17
|
+
class SemanticEngineManager {
|
|
18
|
+
constructor(options = {}) {
|
|
19
|
+
this.options = {
|
|
20
|
+
verbose: options.verbose || false,
|
|
21
|
+
maxSemanticFiles: options.maxSemanticFiles,
|
|
22
|
+
...options
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
// Get the singleton registry
|
|
26
|
+
this.registry = getRegistry();
|
|
27
|
+
this.initialized = false;
|
|
28
|
+
this.projectPath = null;
|
|
29
|
+
this.targetFiles = null;
|
|
30
|
+
|
|
31
|
+
// Statistics
|
|
32
|
+
this.stats = {
|
|
33
|
+
totalFilesAnalyzed: 0,
|
|
34
|
+
filesByLanguage: {},
|
|
35
|
+
analysisTime: 0,
|
|
36
|
+
initializationTime: 0
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Register a language analyzer
|
|
42
|
+
* @param {ILanguageAnalyzer} analyzer - Analyzer instance
|
|
43
|
+
*/
|
|
44
|
+
registerAnalyzer(analyzer) {
|
|
45
|
+
this.registry.register(analyzer);
|
|
46
|
+
if (this.options.verbose) {
|
|
47
|
+
console.log(`📝 SemanticEngineManager: Registered ${analyzer.name} analyzer`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Unregister a language analyzer
|
|
53
|
+
* @param {string} name - Analyzer name
|
|
54
|
+
*/
|
|
55
|
+
unregisterAnalyzer(name) {
|
|
56
|
+
this.registry.unregister(name);
|
|
57
|
+
if (this.options.verbose) {
|
|
58
|
+
console.log(`📝 SemanticEngineManager: Unregistered ${name} analyzer`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Initialize all registered analyzers
|
|
64
|
+
* @param {string} projectPath - Project root path
|
|
65
|
+
* @param {string[]} [targetFiles] - Specific files to analyze
|
|
66
|
+
* @returns {Promise<boolean>} - True if at least one analyzer initialized successfully
|
|
67
|
+
*/
|
|
68
|
+
async initialize(projectPath, targetFiles = null) {
|
|
69
|
+
const startTime = Date.now();
|
|
70
|
+
this.projectPath = projectPath;
|
|
71
|
+
this.targetFiles = targetFiles;
|
|
72
|
+
|
|
73
|
+
if (this.options.verbose) {
|
|
74
|
+
console.log(`🚀 SemanticEngineManager: Initializing with ${this.registry.getNames().length} analyzers`);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Group target files by language for each analyzer
|
|
78
|
+
const filesByAnalyzer = this.groupFilesByAnalyzer(targetFiles);
|
|
79
|
+
|
|
80
|
+
// Initialize each analyzer with its relevant files
|
|
81
|
+
const config = {
|
|
82
|
+
projectPath,
|
|
83
|
+
verbose: this.options.verbose,
|
|
84
|
+
maxSemanticFiles: this.options.maxSemanticFiles,
|
|
85
|
+
compilerOptions: this.options.compilerOptions
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
let anySuccess = false;
|
|
89
|
+
|
|
90
|
+
for (const [analyzerName, files] of filesByAnalyzer) {
|
|
91
|
+
const analyzer = this.registry.get(analyzerName);
|
|
92
|
+
if (!analyzer) continue;
|
|
93
|
+
|
|
94
|
+
try {
|
|
95
|
+
const analyzerConfig = {
|
|
96
|
+
...config,
|
|
97
|
+
targetFiles: files
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
const success = await analyzer.initialize(analyzerConfig);
|
|
101
|
+
if (success) {
|
|
102
|
+
anySuccess = true;
|
|
103
|
+
if (this.options.verbose) {
|
|
104
|
+
console.log(`✅ ${analyzerName} analyzer initialized with ${files.length} files`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
} catch (error) {
|
|
108
|
+
console.error(`❌ Failed to initialize ${analyzerName} analyzer:`, error.message);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Also initialize analyzers that don't have matching files
|
|
113
|
+
// (they might be needed for on-demand analysis)
|
|
114
|
+
for (const analyzer of this.registry.getAll()) {
|
|
115
|
+
if (!filesByAnalyzer.has(analyzer.name)) {
|
|
116
|
+
try {
|
|
117
|
+
const success = await analyzer.initialize(config);
|
|
118
|
+
if (success) {
|
|
119
|
+
anySuccess = true;
|
|
120
|
+
}
|
|
121
|
+
} catch (error) {
|
|
122
|
+
// Silently skip - no files for this analyzer
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
this.initialized = anySuccess;
|
|
128
|
+
this.stats.initializationTime = Date.now() - startTime;
|
|
129
|
+
|
|
130
|
+
if (this.options.verbose) {
|
|
131
|
+
console.log(`🔧 SemanticEngineManager initialized in ${this.stats.initializationTime}ms`);
|
|
132
|
+
console.log(` 📊 Active analyzers: ${this.registry.getNames().filter(n => this.registry.get(n)?.isReady()).join(', ')}`);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return anySuccess;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Group files by their corresponding analyzer
|
|
140
|
+
* @param {string[]|null} files - Files to group
|
|
141
|
+
* @returns {Map<string, string[]>} - Map of analyzer name to files
|
|
142
|
+
*/
|
|
143
|
+
groupFilesByAnalyzer(files) {
|
|
144
|
+
const grouped = new Map();
|
|
145
|
+
|
|
146
|
+
if (!files) {
|
|
147
|
+
return grouped;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
for (const file of files) {
|
|
151
|
+
const analyzer = this.registry.getForFile(file);
|
|
152
|
+
if (analyzer) {
|
|
153
|
+
if (!grouped.has(analyzer.name)) {
|
|
154
|
+
grouped.set(analyzer.name, []);
|
|
155
|
+
}
|
|
156
|
+
grouped.get(analyzer.name).push(file);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
return grouped;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Get the analyzer for a specific file
|
|
165
|
+
* @param {string} filePath - Path to the file
|
|
166
|
+
* @returns {ILanguageAnalyzer|null} - Analyzer or null
|
|
167
|
+
*/
|
|
168
|
+
getAnalyzerForFile(filePath) {
|
|
169
|
+
return this.registry.getForFile(filePath);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Get the Symbol Table for a file
|
|
174
|
+
* Routes to the appropriate language analyzer
|
|
175
|
+
* @param {string} filePath - Absolute path to the file
|
|
176
|
+
* @returns {Promise<Object|null>} - Symbol table or null
|
|
177
|
+
*/
|
|
178
|
+
async getSymbolTable(filePath) {
|
|
179
|
+
const analyzer = this.registry.getForFile(filePath);
|
|
180
|
+
if (!analyzer || !analyzer.isReady()) {
|
|
181
|
+
if (this.options.verbose) {
|
|
182
|
+
console.warn(`⚠️ No ready analyzer for: ${path.basename(filePath)}`);
|
|
183
|
+
}
|
|
184
|
+
return null;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
try {
|
|
188
|
+
return await analyzer.getSymbolTable(filePath);
|
|
189
|
+
} catch (error) {
|
|
190
|
+
console.error(`❌ Error getting symbol table for ${filePath}:`, error.message);
|
|
191
|
+
return null;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Analyze a single file
|
|
197
|
+
* @param {string} filePath - Path to the file
|
|
198
|
+
* @param {Object[]} rules - Rules to apply
|
|
199
|
+
* @param {Object} [options] - Analysis options
|
|
200
|
+
* @returns {Promise<Object[]>} - Array of violations
|
|
201
|
+
*/
|
|
202
|
+
async analyzeFile(filePath, rules, options = {}) {
|
|
203
|
+
const analyzer = this.registry.getForFile(filePath);
|
|
204
|
+
if (!analyzer || !analyzer.isReady()) {
|
|
205
|
+
if (this.options.verbose) {
|
|
206
|
+
console.warn(`⚠️ No ready analyzer for: ${path.basename(filePath)}`);
|
|
207
|
+
}
|
|
208
|
+
return [];
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
try {
|
|
212
|
+
const startTime = Date.now();
|
|
213
|
+
const violations = await analyzer.analyzeFile(filePath, rules, options);
|
|
214
|
+
|
|
215
|
+
this.stats.totalFilesAnalyzed++;
|
|
216
|
+
this.stats.filesByLanguage[analyzer.name] = (this.stats.filesByLanguage[analyzer.name] || 0) + 1;
|
|
217
|
+
this.stats.analysisTime += Date.now() - startTime;
|
|
218
|
+
|
|
219
|
+
return violations;
|
|
220
|
+
} catch (error) {
|
|
221
|
+
console.error(`❌ Error analyzing ${filePath}:`, error.message);
|
|
222
|
+
return [];
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Analyze multiple files
|
|
228
|
+
* Routes each file to its appropriate analyzer
|
|
229
|
+
* @param {string[]} files - Files to analyze
|
|
230
|
+
* @param {Object[]} rules - Rules to apply
|
|
231
|
+
* @param {Object} [options] - Analysis options
|
|
232
|
+
* @returns {Promise<Object[]>} - Array of violations
|
|
233
|
+
*/
|
|
234
|
+
async analyzeFiles(files, rules, options = {}) {
|
|
235
|
+
const allViolations = [];
|
|
236
|
+
const filesByAnalyzer = this.groupFilesByAnalyzer(files);
|
|
237
|
+
|
|
238
|
+
for (const [analyzerName, analyzerFiles] of filesByAnalyzer) {
|
|
239
|
+
const analyzer = this.registry.get(analyzerName);
|
|
240
|
+
if (!analyzer || !analyzer.isReady()) {
|
|
241
|
+
continue;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
try {
|
|
245
|
+
const violations = await analyzer.analyzeFiles(analyzerFiles, rules, options);
|
|
246
|
+
allViolations.push(...violations);
|
|
247
|
+
|
|
248
|
+
this.stats.filesByLanguage[analyzerName] =
|
|
249
|
+
(this.stats.filesByLanguage[analyzerName] || 0) + analyzerFiles.length;
|
|
250
|
+
} catch (error) {
|
|
251
|
+
console.error(`❌ Error analyzing files with ${analyzerName}:`, error.message);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
this.stats.totalFilesAnalyzed += files.length;
|
|
256
|
+
return allViolations;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Check if the manager is ready for analysis
|
|
261
|
+
* @returns {boolean} - True if at least one analyzer is ready
|
|
262
|
+
*/
|
|
263
|
+
isReady() {
|
|
264
|
+
return this.initialized && this.registry.getAll().some(a => a.isReady());
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* Check if a file is supported
|
|
269
|
+
* @param {string} filePath - Path to the file
|
|
270
|
+
* @returns {boolean} - True if supported
|
|
271
|
+
*/
|
|
272
|
+
supportsFile(filePath) {
|
|
273
|
+
return this.registry.supportsFile(filePath);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Get all supported extensions
|
|
278
|
+
* @returns {string[]} - Array of extensions
|
|
279
|
+
*/
|
|
280
|
+
getSupportedExtensions() {
|
|
281
|
+
return this.registry.getSupportedExtensions();
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Get analyzer by name
|
|
286
|
+
* @param {string} name - Analyzer name
|
|
287
|
+
* @returns {ILanguageAnalyzer|null} - Analyzer or null
|
|
288
|
+
*/
|
|
289
|
+
getAnalyzer(name) {
|
|
290
|
+
return this.registry.get(name);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* Get all registered analyzer names
|
|
295
|
+
* @returns {string[]} - Analyzer names
|
|
296
|
+
*/
|
|
297
|
+
getAnalyzerNames() {
|
|
298
|
+
return this.registry.getNames();
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Get statistics
|
|
303
|
+
* @returns {Object} - Statistics object
|
|
304
|
+
*/
|
|
305
|
+
getStats() {
|
|
306
|
+
return {
|
|
307
|
+
...this.stats,
|
|
308
|
+
analyzers: this.registry.getCombinedStats()
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* Check if Symbol Table analysis is available
|
|
314
|
+
* (Backward compatibility with SemanticEngine)
|
|
315
|
+
* @returns {boolean} - True if available
|
|
316
|
+
*/
|
|
317
|
+
isSymbolEngineReady() {
|
|
318
|
+
return this.isReady();
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* Cleanup all analyzers
|
|
323
|
+
* @returns {Promise<void>}
|
|
324
|
+
*/
|
|
325
|
+
async cleanup() {
|
|
326
|
+
if (this.options.verbose) {
|
|
327
|
+
console.log(`🧹 SemanticEngineManager: Cleaning up ${this.registry.getNames().length} analyzers`);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
await this.registry.disposeAll();
|
|
331
|
+
|
|
332
|
+
// Print final stats
|
|
333
|
+
if (this.options.verbose) {
|
|
334
|
+
console.log(`📊 SemanticEngineManager Stats:`);
|
|
335
|
+
console.log(` 📄 Files analyzed: ${this.stats.totalFilesAnalyzed}`);
|
|
336
|
+
console.log(` ⏱️ Total analysis time: ${this.stats.analysisTime}ms`);
|
|
337
|
+
for (const [lang, count] of Object.entries(this.stats.filesByLanguage)) {
|
|
338
|
+
console.log(` 📝 ${lang}: ${count} files`);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
this.initialized = false;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
// Singleton instance
|
|
347
|
+
let managerInstance = null;
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* Get the singleton manager instance
|
|
351
|
+
* @param {Object} [options] - Options for initialization
|
|
352
|
+
* @returns {SemanticEngineManager}
|
|
353
|
+
*/
|
|
354
|
+
function getManager(options = {}) {
|
|
355
|
+
if (!managerInstance) {
|
|
356
|
+
managerInstance = new SemanticEngineManager(options);
|
|
357
|
+
}
|
|
358
|
+
return managerInstance;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
* Reset the singleton manager (for testing)
|
|
363
|
+
*/
|
|
364
|
+
function resetManager() {
|
|
365
|
+
if (managerInstance) {
|
|
366
|
+
managerInstance.cleanup().catch(console.error);
|
|
367
|
+
}
|
|
368
|
+
managerInstance = null;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
module.exports = {
|
|
372
|
+
SemanticEngineManager,
|
|
373
|
+
getManager,
|
|
374
|
+
resetManager
|
|
375
|
+
};
|
package/core/semantic-engine.js
CHANGED
|
@@ -101,12 +101,7 @@ class SemanticEngine {
|
|
|
101
101
|
/\.(ts|tsx|js|jsx)$/i.test(filePath)
|
|
102
102
|
);
|
|
103
103
|
|
|
104
|
-
|
|
105
|
-
console.log(`🎯 Targeted files received: ${targetFiles.length} total, ${semanticFiles.length} TypeScript/JavaScript files (TS/TSX/JS/JSX)`);
|
|
106
|
-
if (semanticFiles.length < 10) {
|
|
107
|
-
console.log(` Files: ${semanticFiles.map(f => path.basename(f)).join(', ')}`);
|
|
108
|
-
}
|
|
109
|
-
}
|
|
104
|
+
// Silent file targeting - no verbose log needed
|
|
110
105
|
|
|
111
106
|
// Adaptive loading strategy based on project size and user preference
|
|
112
107
|
const userMaxFiles = this.options.maxSemanticFiles;
|
|
@@ -115,21 +110,15 @@ class SemanticEngine {
|
|
|
115
110
|
if (userMaxFiles === -1) {
|
|
116
111
|
// Unlimited: Load all files
|
|
117
112
|
maxFiles = semanticFiles.length;
|
|
118
|
-
console.log(`🔧 Semantic Engine config: UNLIMITED analysis (all ${semanticFiles.length} files)`);
|
|
119
113
|
} else if (userMaxFiles === 0) {
|
|
120
114
|
// Disable semantic analysis
|
|
121
115
|
maxFiles = 0;
|
|
122
|
-
console.log(`🔧 Semantic Engine config: DISABLED semantic analysis (heuristic only mode)`);
|
|
123
|
-
console.log(` 💡 Semantic analysis explicitly disabled with --max-semantic-files=0`);
|
|
124
|
-
console.log(` 💡 To enable: omit the option (default: 1000) or use --max-semantic-files=1000 (or higher)`);
|
|
125
116
|
} else if (userMaxFiles > 0) {
|
|
126
117
|
// User-specified limit
|
|
127
118
|
maxFiles = Math.min(userMaxFiles, semanticFiles.length);
|
|
128
|
-
console.log(`🔧 Semantic Engine config: USER limit ${maxFiles} files (requested: ${userMaxFiles})`);
|
|
129
119
|
} else {
|
|
130
120
|
// Auto-detect based on project size
|
|
131
121
|
maxFiles = semanticFiles.length > 1000 ? 1000 : semanticFiles.length;
|
|
132
|
-
console.log(`🔧 Semantic Engine config: AUTO limit ${maxFiles} files (project has ${semanticFiles.length} files)`);
|
|
133
122
|
}
|
|
134
123
|
|
|
135
124
|
if (this.options.verbose) {
|
|
@@ -142,64 +131,28 @@ class SemanticEngine {
|
|
|
142
131
|
|
|
143
132
|
// Skip semantic analysis if disabled
|
|
144
133
|
if (maxFiles === 0) {
|
|
145
|
-
console.log(`⚠️ Semantic analysis DISABLED - using heuristic rules only`);
|
|
146
|
-
console.log(`💡 To enable semantic analysis, use --max-semantic-files=1000 (or higher)`);
|
|
147
134
|
this.initialized = true;
|
|
148
135
|
return true;
|
|
149
136
|
}
|
|
150
137
|
|
|
151
138
|
if (semanticFiles.length > maxFiles && maxFiles !== semanticFiles.length) {
|
|
152
|
-
console.warn(`⚠️ Large semantic project detected (${semanticFiles.length} files)`);
|
|
153
|
-
console.warn(`⚠️ Loading ${maxFiles} files for memory optimization (${Math.round(maxFiles/semanticFiles.length*100)}% coverage)`);
|
|
154
|
-
if (userMaxFiles !== -1) {
|
|
155
|
-
console.warn(`⚠️ Use --max-semantic-files=-1 to analyze ALL files (unlimited)`);
|
|
156
|
-
console.warn(`⚠️ Use --max-semantic-files=${semanticFiles.length} to analyze exactly this project`);
|
|
157
|
-
}
|
|
158
|
-
|
|
159
139
|
const filesToLoad = semanticFiles.slice(0, maxFiles);
|
|
160
|
-
|
|
140
|
+
|
|
161
141
|
// Load files one by one to handle any parse errors gracefully
|
|
162
|
-
let successCount = 0;
|
|
163
|
-
let errorCount = 0;
|
|
164
|
-
|
|
165
142
|
for (const filePath of filesToLoad) {
|
|
166
143
|
try {
|
|
167
144
|
if (require('fs').existsSync(filePath)) {
|
|
168
145
|
this.project.addSourceFileAtPath(filePath);
|
|
169
|
-
successCount++;
|
|
170
|
-
} else {
|
|
171
|
-
errorCount++;
|
|
172
146
|
}
|
|
173
147
|
} catch (error) {
|
|
174
|
-
|
|
175
|
-
console.warn(`❌ Failed to load: ${path.basename(filePath)} - ${error.message}`);
|
|
176
|
-
}
|
|
177
|
-
errorCount++;
|
|
148
|
+
// Silent error handling
|
|
178
149
|
}
|
|
179
150
|
}
|
|
180
|
-
|
|
181
|
-
console.log(`📊 Semantic analysis: ${successCount} files loaded, ${errorCount} skipped`);
|
|
182
|
-
|
|
183
151
|
} else {
|
|
184
|
-
console.log(`📊 Loading all ${semanticFiles.length} files for complete semantic analysis`);
|
|
185
152
|
// For projects within limits, load all files
|
|
186
153
|
this.project.addSourceFilesAtPaths(semanticFiles);
|
|
187
154
|
}
|
|
188
155
|
|
|
189
|
-
// Debug what ts-morph actually loaded
|
|
190
|
-
const actualFiles = this.project.getSourceFiles();
|
|
191
|
-
console.log(`📊 ts-morph loaded: ${actualFiles.length} files (expected: ${semanticFiles.length})`);
|
|
192
|
-
if (actualFiles.length > semanticFiles.length * 2) {
|
|
193
|
-
console.warn(`⚠️ ts-morph auto-discovered additional files (dependency resolution)`);
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
console.log(`🔧 Semantic Engine initialized (Memory Optimized):`);
|
|
197
|
-
console.log(` 📁 Project: ${projectPath}`);
|
|
198
|
-
console.log(` 📋 TS Config: ${tsConfigPath || 'default (minimal)'}`);
|
|
199
|
-
console.log(` 📄 Files loaded: ${this.project.getSourceFiles().length}`);
|
|
200
|
-
console.log(` 🎯 Targeting mode: ${targetFiles ? 'Filtered files' : 'Auto-discovery'}`);
|
|
201
|
-
console.log(` 💾 Memory mode: Optimized for large projects`);
|
|
202
|
-
|
|
203
156
|
this.initialized = true;
|
|
204
157
|
return true;
|
|
205
158
|
|
|
@@ -587,7 +540,7 @@ class SemanticEngine {
|
|
|
587
540
|
}
|
|
588
541
|
}
|
|
589
542
|
|
|
590
|
-
|
|
543
|
+
// Silent file discovery
|
|
591
544
|
return targetFiles;
|
|
592
545
|
|
|
593
546
|
} catch (error) {
|
|
@@ -626,12 +579,6 @@ class SemanticEngine {
|
|
|
626
579
|
// Clear caches
|
|
627
580
|
this.fileCache.clear();
|
|
628
581
|
this.symbolTable.clear();
|
|
629
|
-
|
|
630
|
-
console.log(`📊 Semantic Engine Stats:`);
|
|
631
|
-
console.log(` 📄 Files analyzed: ${this.stats.filesAnalyzed}`);
|
|
632
|
-
console.log(` 🎯 Cache hits: ${this.stats.cacheHits}`);
|
|
633
|
-
console.log(` ❌ Cache misses: ${this.stats.cacheMisses}`);
|
|
634
|
-
console.log(` 💾 Memory usage: ${Math.round(this.stats.memoryUsage / 1024 / 1024)}MB`);
|
|
635
582
|
}
|
|
636
583
|
}
|
|
637
584
|
|
|
@@ -172,23 +172,41 @@ class UnifiedRuleRegistry {
|
|
|
172
172
|
|
|
173
173
|
if (matchingFolder) {
|
|
174
174
|
const rulePath = path.join(commonRulesDir, matchingFolder);
|
|
175
|
-
|
|
176
|
-
|
|
175
|
+
const tsSubPath = path.join(rulePath, 'typescript');
|
|
176
|
+
|
|
177
|
+
// Check for different analyzer files - first at root, then in typescript/
|
|
177
178
|
const analyzerFiles = {
|
|
178
179
|
semantic: path.join(rulePath, 'semantic-analyzer.js'),
|
|
179
180
|
ast: path.join(rulePath, 'ast-analyzer.js'),
|
|
180
181
|
regex: path.join(rulePath, 'regex-analyzer.js'),
|
|
181
|
-
legacy: path.join(rulePath, 'analyzer.js')
|
|
182
|
+
legacy: path.join(rulePath, 'analyzer.js'),
|
|
183
|
+
router: path.join(rulePath, 'index.js') // Multi-language router
|
|
182
184
|
};
|
|
183
|
-
|
|
185
|
+
|
|
186
|
+
// Also check typescript/ subfolder for multi-language rules
|
|
187
|
+
const tsAnalyzerFiles = {
|
|
188
|
+
semantic: path.join(tsSubPath, 'semantic-analyzer.js'),
|
|
189
|
+
ast: path.join(tsSubPath, 'ast-analyzer.js'),
|
|
190
|
+
regex: path.join(tsSubPath, 'regex-analyzer.js'),
|
|
191
|
+
legacy: path.join(tsSubPath, 'analyzer.js')
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
// First check root level
|
|
184
195
|
for (const [type, filePath] of Object.entries(analyzerFiles)) {
|
|
185
196
|
if (fs.existsSync(filePath)) {
|
|
186
197
|
analyzers[type] = filePath;
|
|
187
198
|
}
|
|
188
199
|
}
|
|
200
|
+
|
|
201
|
+
// Then check typescript/ subfolder (only if not found at root)
|
|
202
|
+
for (const [type, filePath] of Object.entries(tsAnalyzerFiles)) {
|
|
203
|
+
if (!analyzers[type] && fs.existsSync(filePath)) {
|
|
204
|
+
analyzers[type] = filePath;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
189
207
|
}
|
|
190
208
|
}
|
|
191
|
-
|
|
209
|
+
|
|
192
210
|
// Also check other category directories (security, typescript, etc.)
|
|
193
211
|
const otherDirs = ['security', 'typescript', 'react'];
|
|
194
212
|
for (const categoryDir of otherDirs) {
|
|
@@ -202,20 +220,38 @@ class UnifiedRuleRegistry {
|
|
|
202
220
|
|
|
203
221
|
if (matchingFolder) {
|
|
204
222
|
const rulePath = path.join(categoryPath, matchingFolder);
|
|
205
|
-
|
|
223
|
+
const tsSubPath = path.join(rulePath, 'typescript');
|
|
224
|
+
|
|
206
225
|
const analyzerFiles = {
|
|
207
226
|
semantic: path.join(rulePath, 'semantic-analyzer.js'),
|
|
208
227
|
ast: path.join(rulePath, 'ast-analyzer.js'),
|
|
209
228
|
regex: path.join(rulePath, 'regex-analyzer.js'),
|
|
210
|
-
legacy: path.join(rulePath, 'analyzer.js')
|
|
229
|
+
legacy: path.join(rulePath, 'analyzer.js'),
|
|
230
|
+
router: path.join(rulePath, 'index.js') // Multi-language router
|
|
211
231
|
};
|
|
212
|
-
|
|
232
|
+
|
|
233
|
+
// Also check typescript/ subfolder
|
|
234
|
+
const tsAnalyzerFiles = {
|
|
235
|
+
semantic: path.join(tsSubPath, 'semantic-analyzer.js'),
|
|
236
|
+
ast: path.join(tsSubPath, 'ast-analyzer.js'),
|
|
237
|
+
regex: path.join(tsSubPath, 'regex-analyzer.js'),
|
|
238
|
+
legacy: path.join(tsSubPath, 'analyzer.js')
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
// First check root level
|
|
213
242
|
for (const [type, filePath] of Object.entries(analyzerFiles)) {
|
|
214
243
|
if (fs.existsSync(filePath)) {
|
|
215
244
|
analyzers[type] = filePath;
|
|
216
245
|
}
|
|
217
246
|
}
|
|
218
|
-
|
|
247
|
+
|
|
248
|
+
// Then check typescript/ subfolder (only if not found at root)
|
|
249
|
+
for (const [type, filePath] of Object.entries(tsAnalyzerFiles)) {
|
|
250
|
+
if (!analyzers[type] && fs.existsSync(filePath)) {
|
|
251
|
+
analyzers[type] = filePath;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
219
255
|
// If we found analyzers, stop searching
|
|
220
256
|
if (Object.keys(analyzers).length > 0) {
|
|
221
257
|
break;
|
|
@@ -223,7 +259,7 @@ class UnifiedRuleRegistry {
|
|
|
223
259
|
}
|
|
224
260
|
}
|
|
225
261
|
}
|
|
226
|
-
|
|
262
|
+
|
|
227
263
|
return analyzers;
|
|
228
264
|
}
|
|
229
265
|
|
|
@@ -410,7 +446,12 @@ class UnifiedRuleRegistry {
|
|
|
410
446
|
if (analyzers.legacy && (capabilities.includes('regex') || capabilities.includes('ast'))) {
|
|
411
447
|
return analyzers.legacy;
|
|
412
448
|
}
|
|
413
|
-
|
|
449
|
+
|
|
450
|
+
// Fall back to router (index.js) for multi-language support
|
|
451
|
+
if (analyzers.router) {
|
|
452
|
+
return analyzers.router;
|
|
453
|
+
}
|
|
454
|
+
|
|
414
455
|
return null;
|
|
415
456
|
}
|
|
416
457
|
|
package/core/upload-service.js
CHANGED
|
@@ -24,15 +24,49 @@ class UploadService {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
const uploadResult = await this.executeUploadCommand(filePath, apiUrl, options);
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
27
|
+
|
|
28
|
+
// Check if upload was actually successful based on HTTP status code
|
|
29
|
+
const statusCode = uploadResult.statusCode;
|
|
30
|
+
const isSuccess = statusCode >= 200 && statusCode < 300;
|
|
31
|
+
|
|
32
|
+
if (isSuccess) {
|
|
33
|
+
console.log(chalk.green(`✅ Report uploaded successfully!`));
|
|
34
|
+
console.log(chalk.green(`📡 HTTP Status: ${statusCode}`));
|
|
35
|
+
return {
|
|
36
|
+
success: true,
|
|
37
|
+
url: apiUrl,
|
|
38
|
+
filePath: filePath,
|
|
39
|
+
response: uploadResult.response,
|
|
40
|
+
statusCode: statusCode
|
|
41
|
+
};
|
|
42
|
+
} else {
|
|
43
|
+
// Handle non-success HTTP status codes
|
|
44
|
+
const errorMessages = {
|
|
45
|
+
401: 'Unauthorized - Authentication required. Make sure OIDC token is configured correctly.',
|
|
46
|
+
403: 'Forbidden - Access denied. Check your permissions.',
|
|
47
|
+
404: 'Not Found - API endpoint does not exist.',
|
|
48
|
+
500: 'Internal Server Error - Server-side issue.',
|
|
49
|
+
502: 'Bad Gateway - Server is temporarily unavailable.',
|
|
50
|
+
503: 'Service Unavailable - Server is overloaded or under maintenance.'
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const errorMessage = errorMessages[statusCode] || `HTTP Error ${statusCode}`;
|
|
54
|
+
console.error(chalk.red(`❌ Upload failed: ${errorMessage}`));
|
|
55
|
+
console.error(chalk.red(`📡 HTTP Status: ${statusCode}`));
|
|
56
|
+
|
|
57
|
+
if (uploadResult.response) {
|
|
58
|
+
console.error(chalk.yellow(`📄 Response: ${uploadResult.response}`));
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return {
|
|
62
|
+
success: false,
|
|
63
|
+
url: apiUrl,
|
|
64
|
+
filePath: filePath,
|
|
65
|
+
response: uploadResult.response,
|
|
66
|
+
statusCode: statusCode,
|
|
67
|
+
error: errorMessage
|
|
68
|
+
};
|
|
69
|
+
}
|
|
36
70
|
|
|
37
71
|
} catch (error) {
|
|
38
72
|
const errorContext = {
|