@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.
Files changed (456) hide show
  1. package/README.md +47 -0
  2. package/config/released-rules.json +62 -0
  3. package/config/rules/enhanced-rules-registry.json +2315 -1354
  4. package/core/adapters/dart-analyzer.js +658 -0
  5. package/core/adapters/index.js +102 -0
  6. package/core/adapters/sunlint-rule-adapter.js +0 -2
  7. package/core/adapters/typescript-analyzer.js +277 -0
  8. package/core/analysis-orchestrator.js +168 -40
  9. package/core/architecture-integration.js +220 -0
  10. package/core/cli-action-handler.js +72 -24
  11. package/core/cli-program.js +13 -1
  12. package/core/config-merger.js +24 -14
  13. package/core/constants/defaults.js +1 -2
  14. package/core/github-annotate-service.js +141 -89
  15. package/core/github-step-summary-generator.js +8 -8
  16. package/core/interfaces/language-analyzer.interface.js +393 -0
  17. package/core/output-service.js +102 -38
  18. package/core/rule-selection-service.js +77 -27
  19. package/core/scoring-service.js +65 -20
  20. package/core/semantic-engine-manager.js +375 -0
  21. package/core/semantic-engine.js +4 -57
  22. package/core/unified-rule-registry.js +52 -11
  23. package/core/upload-service.js +43 -9
  24. package/docs/DART_RULE_EXECUTION_FLOW.md +745 -0
  25. package/docs/DART_SUPPORT_IMPLEMENTATION.md +245 -0
  26. package/docs/SUNLINT_ARCHITECTURE.md +692 -0
  27. package/docs/skills/CREATE_DART_RULE.md +909 -0
  28. package/engines/eslint-engine.js +2 -8
  29. package/engines/heuristic-engine.js +234 -38
  30. package/package.json +6 -5
  31. package/rules/common/C002_no_duplicate_code/config.json +12 -20
  32. package/rules/common/C002_no_duplicate_code/dart/analyzer.js +53 -0
  33. package/rules/common/C002_no_duplicate_code/index.js +93 -0
  34. package/rules/common/C003_no_vague_abbreviations/config.json +1 -1
  35. package/rules/common/C003_no_vague_abbreviations/dart/analyzer.js +54 -0
  36. package/rules/common/C003_no_vague_abbreviations/index.js +93 -0
  37. package/rules/common/C006_function_naming/dart/analyzer.js +40 -0
  38. package/rules/common/C006_function_naming/index.js +86 -0
  39. package/rules/common/C008_variable_declaration_locality/dart/analyzer.js +32 -0
  40. package/rules/common/C008_variable_declaration_locality/index.js +86 -0
  41. package/rules/common/C010_limit_block_nesting/dart/analyzer.js +32 -0
  42. package/rules/common/C010_limit_block_nesting/index.js +86 -0
  43. package/rules/common/C012_command_query_separation/config.json +61 -0
  44. package/rules/common/C012_command_query_separation/dart/analyzer.js +32 -0
  45. package/rules/common/C012_command_query_separation/index.js +86 -0
  46. package/rules/common/C013_no_dead_code/dart/analyzer.js +32 -0
  47. package/rules/common/C013_no_dead_code/index.js +86 -0
  48. package/rules/common/C014_dependency_injection/dart/analyzer.js +32 -0
  49. package/rules/common/C014_dependency_injection/index.js +86 -0
  50. package/rules/common/C017_constructor_logic/dart/analyzer.js +32 -0
  51. package/rules/common/C017_constructor_logic/index.js +86 -0
  52. package/rules/common/C018_no_throw_generic_error/dart/analyzer.js +32 -0
  53. package/rules/common/C018_no_throw_generic_error/index.js +86 -0
  54. package/rules/common/C019_log_level_usage/dart/analyzer.js +32 -0
  55. package/rules/common/C019_log_level_usage/index.js +86 -0
  56. package/rules/common/C019_log_level_usage/{ts-morph-analyzer.js → typescript/ts-morph-analyzer.js} +0 -1
  57. package/rules/common/C020_unused_imports/dart/analyzer.js +32 -0
  58. package/rules/common/C020_unused_imports/index.js +86 -0
  59. package/rules/common/C020_unused_imports/{ts-morph-analyzer.js → typescript/ts-morph-analyzer.js} +0 -1
  60. package/rules/common/C021_import_organization/config.json +29 -9
  61. package/rules/common/C021_import_organization/dart/analyzer.js +40 -0
  62. package/rules/common/C021_import_organization/index.js +83 -0
  63. package/rules/common/C021_import_organization/{ts-morph-analyzer.js → typescript/ts-morph-analyzer.js} +0 -1
  64. package/rules/common/C023_no_duplicate_variable/config.json +7 -2
  65. package/rules/common/C023_no_duplicate_variable/dart/analyzer.js +40 -0
  66. package/rules/common/C023_no_duplicate_variable/index.js +83 -0
  67. package/rules/common/C024_no_scatter_hardcoded_constants/config.json +7 -2
  68. package/rules/common/C024_no_scatter_hardcoded_constants/dart/analyzer.js +40 -0
  69. package/rules/common/C024_no_scatter_hardcoded_constants/index.js +83 -0
  70. package/rules/common/C024_no_scatter_hardcoded_constants/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +19 -1
  71. package/rules/common/C029_catch_block_logging/config.json +15 -5
  72. package/rules/common/C029_catch_block_logging/dart/analyzer.js +40 -0
  73. package/rules/common/C029_catch_block_logging/index.js +83 -0
  74. package/rules/common/C030_use_custom_error_classes/config.json +28 -0
  75. package/rules/common/C030_use_custom_error_classes/dart/analyzer.js +40 -0
  76. package/rules/common/C030_use_custom_error_classes/index.js +83 -0
  77. package/rules/common/C031_validation_separation/config.json +28 -0
  78. package/rules/common/C031_validation_separation/dart/analyzer.js +40 -0
  79. package/rules/common/C031_validation_separation/index.js +83 -0
  80. package/rules/common/C033_separate_service_repository/config.json +8 -3
  81. package/rules/common/C033_separate_service_repository/dart/analyzer.js +40 -0
  82. package/rules/common/C033_separate_service_repository/index.js +83 -0
  83. package/rules/common/C035_error_logging_context/config.json +34 -12
  84. package/rules/common/C035_error_logging_context/dart/analyzer.js +40 -0
  85. package/rules/common/C035_error_logging_context/index.js +83 -0
  86. package/rules/common/C040_centralized_validation/config.json +37 -8
  87. package/rules/common/C040_centralized_validation/dart/analyzer.js +40 -0
  88. package/rules/common/C040_centralized_validation/index.js +83 -0
  89. package/rules/common/C041_no_sensitive_hardcode/config.json +7 -2
  90. package/rules/common/C041_no_sensitive_hardcode/dart/analyzer.js +40 -0
  91. package/rules/common/C041_no_sensitive_hardcode/index.js +83 -0
  92. package/rules/common/C042_boolean_name_prefix/config.json +28 -0
  93. package/rules/common/C042_boolean_name_prefix/dart/analyzer.js +40 -0
  94. package/rules/common/C042_boolean_name_prefix/index.js +83 -0
  95. package/rules/common/C043_no_console_or_print/config.json +28 -0
  96. package/rules/common/C043_no_console_or_print/dart/analyzer.js +40 -0
  97. package/rules/common/C043_no_console_or_print/index.js +83 -0
  98. package/rules/common/C047_no_duplicate_retry_logic/config.json +28 -0
  99. package/rules/common/C047_no_duplicate_retry_logic/dart/analyzer.js +40 -0
  100. package/rules/common/C047_no_duplicate_retry_logic/index.js +83 -0
  101. package/rules/common/C048_no_bypass_architectural_layers/config.json +7 -2
  102. package/rules/common/C048_no_bypass_architectural_layers/dart/analyzer.js +40 -0
  103. package/rules/common/C048_no_bypass_architectural_layers/index.js +83 -0
  104. package/rules/common/C052_parsing_or_data_transformation/config.json +7 -2
  105. package/rules/common/C052_parsing_or_data_transformation/dart/analyzer.js +40 -0
  106. package/rules/common/C052_parsing_or_data_transformation/index.js +83 -0
  107. package/rules/common/C060_no_override_superclass/config.json +7 -2
  108. package/rules/common/C060_no_override_superclass/dart/analyzer.js +40 -0
  109. package/rules/common/C060_no_override_superclass/index.js +83 -0
  110. package/rules/common/C065_one_behavior_per_test/config.json +187 -28
  111. package/rules/common/C065_one_behavior_per_test/dart/analyzer.js +40 -0
  112. package/rules/common/C065_one_behavior_per_test/index.js +83 -0
  113. package/rules/common/C067_no_hardcoded_config/config.json +18 -4
  114. package/rules/common/C067_no_hardcoded_config/dart/analyzer.js +40 -0
  115. package/rules/common/C067_no_hardcoded_config/index.js +83 -0
  116. package/rules/common/C070_no_real_time_tests/config.json +41 -12
  117. package/rules/common/C070_no_real_time_tests/dart/analyzer.js +40 -0
  118. package/rules/common/C070_no_real_time_tests/index.js +83 -0
  119. package/rules/common/C072_single_test_behavior/config.json +28 -0
  120. package/rules/common/C072_single_test_behavior/dart/analyzer.js +40 -0
  121. package/rules/common/C072_single_test_behavior/index.js +83 -0
  122. package/rules/common/C073_validate_required_config_on_startup/config.json +93 -18
  123. package/rules/common/C073_validate_required_config_on_startup/dart/analyzer.js +40 -0
  124. package/rules/common/C073_validate_required_config_on_startup/index.js +83 -0
  125. package/rules/common/C073_validate_required_config_on_startup/{analyzer.js → typescript/analyzer.js} +0 -1
  126. package/rules/common/C075_explicit_return_types/config.json +28 -0
  127. package/rules/common/C075_explicit_return_types/dart/analyzer.js +40 -0
  128. package/rules/common/C075_explicit_return_types/index.js +83 -0
  129. package/rules/common/C076_explicit_function_types/config.json +18 -4
  130. package/rules/common/C076_explicit_function_types/dart/analyzer.js +40 -0
  131. package/rules/common/C076_explicit_function_types/index.js +83 -0
  132. package/rules/index.js +26 -6
  133. package/rules/security/S003_open_redirect_protection/config.json +11 -53
  134. package/rules/security/S003_open_redirect_protection/dart/analyzer.js +43 -0
  135. package/rules/security/S003_open_redirect_protection/index.js +94 -0
  136. package/rules/security/S003_open_redirect_protection/typescript/analyzer.js +105 -0
  137. package/rules/security/S003_open_redirect_protection/{symbol-based-analyzer.js → typescript/semantic-analyzer.js} +1 -1
  138. package/rules/security/S004_sensitive_data_logging/config.json +1 -1
  139. package/rules/security/S004_sensitive_data_logging/dart/analyzer.js +58 -0
  140. package/rules/security/S004_sensitive_data_logging/index.js +93 -0
  141. package/rules/security/S005_no_origin_auth/dart/analyzer.js +30 -0
  142. package/rules/security/S005_no_origin_auth/index.js +83 -0
  143. package/rules/security/S005_no_origin_auth/{analyzer.js → typescript/analyzer.js} +1 -0
  144. package/rules/security/S006_no_plaintext_recovery_codes/dart/analyzer.js +30 -0
  145. package/rules/security/S006_no_plaintext_recovery_codes/index.js +83 -0
  146. package/rules/security/S007_no_plaintext_otp/dart/analyzer.js +30 -0
  147. package/rules/security/S007_no_plaintext_otp/index.js +83 -0
  148. package/rules/security/S009_no_insecure_encryption/dart/analyzer.js +30 -0
  149. package/rules/security/S009_no_insecure_encryption/index.js +83 -0
  150. package/rules/security/S010_no_insecure_encryption/dart/analyzer.js +30 -0
  151. package/rules/security/S010_no_insecure_encryption/index.js +83 -0
  152. package/rules/security/S011_secure_guid_generation/dart/analyzer.js +30 -0
  153. package/rules/security/S011_secure_guid_generation/index.js +83 -0
  154. package/rules/security/S012_hardcoded_secrets/dart/analyzer.js +30 -0
  155. package/rules/security/S012_hardcoded_secrets/index.js +83 -0
  156. package/rules/security/S012_hardcoded_secrets/typescript/config.json +75 -0
  157. package/rules/security/S013_tls_enforcement/dart/analyzer.js +30 -0
  158. package/rules/security/S013_tls_enforcement/index.js +83 -0
  159. package/rules/security/S014_tls_version_enforcement/dart/analyzer.js +30 -0
  160. package/rules/security/S014_tls_version_enforcement/index.js +83 -0
  161. package/rules/security/S015_insecure_tls_certificate/config.json +41 -0
  162. package/rules/security/S015_insecure_tls_certificate/dart/analyzer.js +19 -0
  163. package/rules/security/S015_insecure_tls_certificate/index.js +83 -0
  164. package/rules/security/S016_no_sensitive_querystring/dart/analyzer.js +30 -0
  165. package/rules/security/S016_no_sensitive_querystring/index.js +83 -0
  166. package/rules/security/S017_use_parameterized_queries/dart/analyzer.js +30 -0
  167. package/rules/security/S017_use_parameterized_queries/index.js +83 -0
  168. package/rules/security/S019_smtp_injection_protection/dart/analyzer.js +30 -0
  169. package/rules/security/S019_smtp_injection_protection/index.js +83 -0
  170. package/rules/security/S020_no_eval_dynamic_code/dart/analyzer.js +30 -0
  171. package/rules/security/S020_no_eval_dynamic_code/index.js +83 -0
  172. package/rules/security/S022_escape_output_context/dart/analyzer.js +30 -0
  173. package/rules/security/S022_escape_output_context/index.js +83 -0
  174. package/rules/security/S023_no_json_injection/dart/analyzer.js +30 -0
  175. package/rules/security/S023_no_json_injection/index.js +83 -0
  176. package/rules/security/S024_xpath_xxe_protection/dart/analyzer.js +30 -0
  177. package/rules/security/S024_xpath_xxe_protection/index.js +83 -0
  178. package/rules/security/S025_server_side_validation/dart/analyzer.js +30 -0
  179. package/rules/security/S025_server_side_validation/index.js +83 -0
  180. package/rules/security/S026_json_schema_validation/dart/analyzer.js +30 -0
  181. package/rules/security/S026_json_schema_validation/index.js +83 -0
  182. package/rules/security/S027_no_hardcoded_secrets/dart/analyzer.js +30 -0
  183. package/rules/security/S027_no_hardcoded_secrets/index.js +83 -0
  184. package/rules/security/S028_file_upload_size_limits/dart/analyzer.js +30 -0
  185. package/rules/security/S028_file_upload_size_limits/index.js +83 -0
  186. package/rules/security/S029_csrf_protection/dart/analyzer.js +30 -0
  187. package/rules/security/S029_csrf_protection/index.js +83 -0
  188. package/rules/security/S030_directory_browsing_protection/dart/analyzer.js +30 -0
  189. package/rules/security/S030_directory_browsing_protection/index.js +83 -0
  190. package/rules/security/S031_secure_session_cookies/dart/analyzer.js +30 -0
  191. package/rules/security/S031_secure_session_cookies/index.js +83 -0
  192. package/rules/security/S032_httponly_session_cookies/dart/analyzer.js +30 -0
  193. package/rules/security/S032_httponly_session_cookies/index.js +83 -0
  194. package/rules/security/S033_samesite_session_cookies/dart/analyzer.js +30 -0
  195. package/rules/security/S033_samesite_session_cookies/index.js +83 -0
  196. package/rules/security/S034_host_prefix_session_cookies/dart/analyzer.js +30 -0
  197. package/rules/security/S034_host_prefix_session_cookies/index.js +83 -0
  198. package/rules/security/S035_path_session_cookies/dart/analyzer.js +30 -0
  199. package/rules/security/S035_path_session_cookies/index.js +83 -0
  200. package/rules/security/S036_lfi_rfi_protection/dart/analyzer.js +30 -0
  201. package/rules/security/S036_lfi_rfi_protection/index.js +83 -0
  202. package/rules/security/S037_cache_headers/dart/analyzer.js +30 -0
  203. package/rules/security/S037_cache_headers/index.js +83 -0
  204. package/rules/security/S038_no_version_headers/dart/analyzer.js +30 -0
  205. package/rules/security/S038_no_version_headers/index.js +83 -0
  206. package/rules/security/S039_no_session_tokens_in_url/dart/analyzer.js +30 -0
  207. package/rules/security/S039_no_session_tokens_in_url/index.js +83 -0
  208. package/rules/security/S040_session_fixation_protection/dart/analyzer.js +30 -0
  209. package/rules/security/S040_session_fixation_protection/index.js +83 -0
  210. package/rules/security/S041_session_token_invalidation/dart/analyzer.js +30 -0
  211. package/rules/security/S041_session_token_invalidation/index.js +83 -0
  212. package/rules/security/S042_require_re_authentication_for_long_lived/dart/analyzer.js +30 -0
  213. package/rules/security/S042_require_re_authentication_for_long_lived/index.js +83 -0
  214. package/rules/security/S043_password_changes_invalidate_all_sessions/dart/analyzer.js +30 -0
  215. package/rules/security/S043_password_changes_invalidate_all_sessions/index.js +83 -0
  216. package/rules/security/S044_re_authentication_required/dart/analyzer.js +30 -0
  217. package/rules/security/S044_re_authentication_required/index.js +83 -0
  218. package/rules/security/S045_brute_force_protection/dart/analyzer.js +30 -0
  219. package/rules/security/S045_brute_force_protection/index.js +83 -0
  220. package/rules/security/S048_no_current_password_in_reset/dart/analyzer.js +30 -0
  221. package/rules/security/S048_no_current_password_in_reset/index.js +83 -0
  222. package/rules/security/S049_short_validity_tokens/dart/analyzer.js +30 -0
  223. package/rules/security/S049_short_validity_tokens/index.js +83 -0
  224. package/rules/security/S049_short_validity_tokens/typescript/config.json +124 -0
  225. package/rules/security/S051_password_length_policy/dart/analyzer.js +30 -0
  226. package/rules/security/S051_password_length_policy/index.js +83 -0
  227. package/rules/security/S051_password_length_policy/typescript/config.json +83 -0
  228. package/rules/security/S052_weak_otp_entropy/dart/analyzer.js +30 -0
  229. package/rules/security/S052_weak_otp_entropy/index.js +83 -0
  230. package/rules/security/S052_weak_otp_entropy/typescript/config.json +57 -0
  231. package/rules/security/S054_no_default_accounts/dart/analyzer.js +30 -0
  232. package/rules/security/S054_no_default_accounts/index.js +83 -0
  233. package/rules/security/S054_no_default_accounts/typescript/config.json +101 -0
  234. package/rules/security/S055_content_type_validation/dart/analyzer.js +30 -0
  235. package/rules/security/S055_content_type_validation/index.js +83 -0
  236. package/rules/security/S056_log_injection_protection/dart/analyzer.js +30 -0
  237. package/rules/security/S056_log_injection_protection/index.js +83 -0
  238. package/rules/security/S057_utc_logging/dart/analyzer.js +30 -0
  239. package/rules/security/S057_utc_logging/index.js +83 -0
  240. package/rules/security/S057_utc_logging/typescript/config.json +105 -0
  241. package/rules/security/S058_no_ssrf/dart/analyzer.js +30 -0
  242. package/rules/security/S058_no_ssrf/index.js +83 -0
  243. package/rules/security/S058_no_ssrf/{analyzer.js → typescript/analyzer.js} +0 -1
  244. package/rules/security/S058_no_ssrf/typescript/config.json +125 -0
  245. package/scripts/build-release.sh +12 -0
  246. package/scripts/copy-arch-detect.js +78 -0
  247. package/rules/common/C002_no_duplicate_code/test-cases/api-handlers.ts +0 -64
  248. package/rules/common/C002_no_duplicate_code/test-cases/data-processor.ts +0 -46
  249. package/rules/common/C002_no_duplicate_code/test-cases/good-example.tsx +0 -40
  250. package/rules/common/C002_no_duplicate_code/test-cases/product-service.ts +0 -57
  251. package/rules/common/C002_no_duplicate_code/test-cases/user-service.ts +0 -49
  252. package/rules/common/C067_no_hardcoded_config/symbol-based-analyzer.js.backup +0 -3853
  253. package/rules/security/S003_open_redirect_protection/analyzer.js +0 -135
  254. /package/rules/common/C002_no_duplicate_code/{analyzer.js → typescript/analyzer.js} +0 -0
  255. /package/rules/common/C003_no_vague_abbreviations/{analyzer.js → typescript/analyzer.js} +0 -0
  256. /package/rules/common/C006_function_naming/{analyzer.js → typescript/analyzer.js} +0 -0
  257. /package/rules/common/{C008 → C008_variable_declaration_locality}/config.json +0 -0
  258. /package/rules/common/{C008 → C008_variable_declaration_locality/typescript}/analyzer.js +0 -0
  259. /package/rules/common/{C008 → C008_variable_declaration_locality/typescript}/ts-morph-analyzer.js +0 -0
  260. /package/rules/common/C010_limit_block_nesting/{analyzer.js → typescript/analyzer.js} +0 -0
  261. /package/rules/common/C010_limit_block_nesting/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
  262. /package/rules/common/C010_limit_block_nesting/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
  263. /package/rules/common/C012_command_query_separation/{analyzer.js → typescript/analyzer.js} +0 -0
  264. /package/rules/common/C012_command_query_separation/{ast-analyzer.js → typescript/ast-analyzer.js} +0 -0
  265. /package/rules/common/C013_no_dead_code/{analyzer.js → typescript/analyzer.js} +0 -0
  266. /package/rules/common/C013_no_dead_code/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
  267. /package/rules/common/C013_no_dead_code/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
  268. /package/rules/common/C014_dependency_injection/{analyzer.js → typescript/analyzer.js} +0 -0
  269. /package/rules/common/C014_dependency_injection/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
  270. /package/rules/common/C017_constructor_logic/{analyzer.js → typescript/analyzer.js} +0 -0
  271. /package/rules/common/C017_constructor_logic/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
  272. /package/rules/common/C018_no_throw_generic_error/{analyzer.js → typescript/analyzer.js} +0 -0
  273. /package/rules/common/C018_no_throw_generic_error/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
  274. /package/rules/common/C018_no_throw_generic_error/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
  275. /package/rules/common/C019_log_level_usage/{analyzer.js → typescript/analyzer.js} +0 -0
  276. /package/rules/common/C019_log_level_usage/{pattern-analyzer.js → typescript/pattern-analyzer.js} +0 -0
  277. /package/rules/common/C019_log_level_usage/{system-log-analyzer.js → typescript/system-log-analyzer.js} +0 -0
  278. /package/rules/common/C020_unused_imports/{analyzer.js → typescript/analyzer.js} +0 -0
  279. /package/rules/common/C021_import_organization/{analyzer.js → typescript/analyzer.js} +0 -0
  280. /package/rules/common/C023_no_duplicate_variable/{analyzer.js → typescript/analyzer.js} +0 -0
  281. /package/rules/common/C023_no_duplicate_variable/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
  282. /package/rules/common/C024_no_scatter_hardcoded_constants/{analyzer.js → typescript/analyzer.js} +0 -0
  283. /package/rules/common/C029_catch_block_logging/{analyzer.js → typescript/analyzer.js} +0 -0
  284. /package/rules/common/C030_use_custom_error_classes/{analyzer.js → typescript/analyzer.js} +0 -0
  285. /package/rules/common/C031_validation_separation/{analyzer.js → typescript/analyzer.js} +0 -0
  286. /package/rules/common/C033_separate_service_repository/{README.md → typescript/README.md} +0 -0
  287. /package/rules/common/C033_separate_service_repository/{analyzer.js → typescript/analyzer.js} +0 -0
  288. /package/rules/common/C033_separate_service_repository/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
  289. /package/rules/common/C033_separate_service_repository/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
  290. /package/rules/common/C035_error_logging_context/{STRATEGY.md → typescript/STRATEGY.md} +0 -0
  291. /package/rules/common/C035_error_logging_context/{analyzer.js → typescript/analyzer.js} +0 -0
  292. /package/rules/common/C035_error_logging_context/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
  293. /package/rules/common/C035_error_logging_context/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
  294. /package/rules/common/C040_centralized_validation/{analyzer.js → typescript/analyzer.js} +0 -0
  295. /package/rules/common/C040_centralized_validation/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
  296. /package/rules/common/C040_centralized_validation/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
  297. /package/rules/common/C041_no_sensitive_hardcode/{analyzer.js → typescript/analyzer.js} +0 -0
  298. /package/rules/common/C041_no_sensitive_hardcode/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
  299. /package/rules/common/C042_boolean_name_prefix/{analyzer.js → typescript/analyzer.js} +0 -0
  300. /package/rules/common/C043_no_console_or_print/{analyzer.js → typescript/analyzer.js} +0 -0
  301. /package/rules/common/C047_no_duplicate_retry_logic/{analyzer.js → typescript/analyzer.js} +0 -0
  302. /package/rules/common/C047_no_duplicate_retry_logic/{c047-semantic-rule.js → typescript/c047-semantic-rule.js} +0 -0
  303. /package/rules/common/C047_no_duplicate_retry_logic/{symbol-analyzer-enhanced.js → typescript/symbol-analyzer-enhanced.js} +0 -0
  304. /package/rules/common/C047_no_duplicate_retry_logic/{symbol-config.json → typescript/symbol-config.json} +0 -0
  305. /package/rules/common/C048_no_bypass_architectural_layers/{analyzer.js → typescript/analyzer.js} +0 -0
  306. /package/rules/common/C048_no_bypass_architectural_layers/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
  307. /package/rules/common/C052_parsing_or_data_transformation/{analyzer.js → typescript/analyzer.js} +0 -0
  308. /package/rules/common/C052_parsing_or_data_transformation/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
  309. /package/rules/common/C060_no_override_superclass/{analyzer.js → typescript/analyzer.js} +0 -0
  310. /package/rules/common/C060_no_override_superclass/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
  311. /package/rules/common/C065_one_behavior_per_test/{analyzer.js → typescript/analyzer.js} +0 -0
  312. /package/rules/common/C067_no_hardcoded_config/{analyzer.js → typescript/analyzer.js} +0 -0
  313. /package/rules/common/C067_no_hardcoded_config/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
  314. /package/rules/common/C070_no_real_time_tests/{analyzer.js → typescript/analyzer.js} +0 -0
  315. /package/rules/common/C070_no_real_time_tests/{regex-analyzer.js → typescript/regex-analyzer.js} +0 -0
  316. /package/rules/common/C072_single_test_behavior/{analyzer.js → typescript/analyzer.js} +0 -0
  317. /package/rules/common/C073_validate_required_config_on_startup/{README.md → typescript/README.md} +0 -0
  318. /package/rules/common/C073_validate_required_config_on_startup/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
  319. /package/rules/common/C075_explicit_return_types/{analyzer.js → typescript/analyzer.js} +0 -0
  320. /package/rules/common/C076_explicit_function_types/{README.md → typescript/README.md} +0 -0
  321. /package/rules/common/C076_explicit_function_types/{analyzer.js → typescript/analyzer.js} +0 -0
  322. /package/rules/common/C076_explicit_function_types/{semantic-analyzer.js → typescript/semantic-analyzer.js} +0 -0
  323. /package/rules/security/S003_open_redirect_protection/{README.md → typescript/README.md} +0 -0
  324. /package/rules/security/S004_sensitive_data_logging/{analyzer.js → typescript/analyzer.js} +0 -0
  325. /package/rules/security/S004_sensitive_data_logging/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
  326. /package/rules/security/S005_no_origin_auth/{README.md → typescript/README.md} +0 -0
  327. /package/rules/security/S005_no_origin_auth/{ast-analyzer.js → typescript/ast-analyzer.js} +0 -0
  328. /package/rules/security/S005_no_origin_auth/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
  329. /package/rules/security/S006_no_plaintext_recovery_codes/{README.md → typescript/README.md} +0 -0
  330. /package/rules/security/S006_no_plaintext_recovery_codes/{analyzer.js → typescript/analyzer.js} +0 -0
  331. /package/rules/security/S006_no_plaintext_recovery_codes/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
  332. /package/rules/security/S007_no_plaintext_otp/{README.md → typescript/README.md} +0 -0
  333. /package/rules/security/S007_no_plaintext_otp/{analyzer.js → typescript/analyzer.js} +0 -0
  334. /package/rules/security/S007_no_plaintext_otp/{semantic-analyzer.js → typescript/semantic-analyzer.js} +0 -0
  335. /package/rules/security/S007_no_plaintext_otp/{semantic-config.json → typescript/semantic-config.json} +0 -0
  336. /package/rules/security/S007_no_plaintext_otp/{semantic-wrapper.js → typescript/semantic-wrapper.js} +0 -0
  337. /package/rules/security/S009_no_insecure_encryption/{README.md → typescript/README.md} +0 -0
  338. /package/rules/security/S009_no_insecure_encryption/{analyzer.js → typescript/analyzer.js} +0 -0
  339. /package/rules/security/S010_no_insecure_encryption/{README.md → typescript/README.md} +0 -0
  340. /package/rules/security/S010_no_insecure_encryption/{analyzer.js → typescript/analyzer.js} +0 -0
  341. /package/rules/security/S011_secure_guid_generation/{README.md → typescript/README.md} +0 -0
  342. /package/rules/security/S011_secure_guid_generation/{analyzer.js → typescript/analyzer.js} +0 -0
  343. /package/rules/security/S011_secure_guid_generation/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
  344. /package/rules/security/S012_hardcoded_secrets/{analyzer.js → typescript/analyzer.js} +0 -0
  345. /package/rules/security/S012_hardcoded_secrets/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
  346. /package/rules/security/S013_tls_enforcement/{README.md → typescript/README.md} +0 -0
  347. /package/rules/security/S013_tls_enforcement/{analyzer.js → typescript/analyzer.js} +0 -0
  348. /package/rules/security/S013_tls_enforcement/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
  349. /package/rules/security/S014_tls_version_enforcement/{README.md → typescript/README.md} +0 -0
  350. /package/rules/security/S014_tls_version_enforcement/{analyzer.js → typescript/analyzer.js} +0 -0
  351. /package/rules/security/S014_tls_version_enforcement/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
  352. /package/rules/security/S015_insecure_tls_certificate/{analyzer.js → typescript/analyzer.js} +0 -0
  353. /package/rules/security/S015_insecure_tls_certificate/{ast-analyzer.js → typescript/ast-analyzer.js} +0 -0
  354. /package/rules/security/S016_no_sensitive_querystring/{analyzer.js → typescript/analyzer.js} +0 -0
  355. /package/rules/security/S016_no_sensitive_querystring/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
  356. /package/rules/security/S016_no_sensitive_querystring/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
  357. /package/rules/security/S017_use_parameterized_queries/{README.md → typescript/README.md} +0 -0
  358. /package/rules/security/S017_use_parameterized_queries/{analyzer.js → typescript/analyzer.js} +0 -0
  359. /package/rules/security/S017_use_parameterized_queries/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
  360. /package/rules/security/S019_smtp_injection_protection/{analyzer.js → typescript/analyzer.js} +0 -0
  361. /package/rules/security/S019_smtp_injection_protection/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
  362. /package/rules/security/S020_no_eval_dynamic_code/{README.md → typescript/README.md} +0 -0
  363. /package/rules/security/S020_no_eval_dynamic_code/{analyzer.js → typescript/analyzer.js} +0 -0
  364. /package/rules/security/S020_no_eval_dynamic_code/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
  365. /package/rules/security/S022_escape_output_context/{README.md → typescript/README.md} +0 -0
  366. /package/rules/security/S022_escape_output_context/{analyzer.js → typescript/analyzer.js} +0 -0
  367. /package/rules/security/S023_no_json_injection/{analyzer.js → typescript/analyzer.js} +0 -0
  368. /package/rules/security/S023_no_json_injection/{ast-analyzer.js → typescript/ast-analyzer.js} +0 -0
  369. /package/rules/security/S024_xpath_xxe_protection/{analyzer.js → typescript/analyzer.js} +0 -0
  370. /package/rules/security/S024_xpath_xxe_protection/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
  371. /package/rules/security/S024_xpath_xxe_protection/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
  372. /package/rules/security/S025_server_side_validation/{README.md → typescript/README.md} +0 -0
  373. /package/rules/security/S025_server_side_validation/{analyzer.js → typescript/analyzer.js} +0 -0
  374. /package/rules/security/S025_server_side_validation/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
  375. /package/rules/security/S025_server_side_validation/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
  376. /package/rules/security/S026_json_schema_validation/{analyzer.js → typescript/analyzer.js} +0 -0
  377. /package/rules/security/S027_no_hardcoded_secrets/{analyzer.js → typescript/analyzer.js} +0 -0
  378. /package/rules/security/S027_no_hardcoded_secrets/{categories.json → typescript/categories.json} +0 -0
  379. /package/rules/security/S027_no_hardcoded_secrets/{categorized-analyzer.js → typescript/categorized-analyzer.js} +0 -0
  380. /package/rules/security/S028_file_upload_size_limits/{README.md → typescript/README.md} +0 -0
  381. /package/rules/security/S028_file_upload_size_limits/{analyzer.js → typescript/analyzer.js} +0 -0
  382. /package/rules/security/S028_file_upload_size_limits/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
  383. /package/rules/security/S029_csrf_protection/{analyzer.js → typescript/analyzer.js} +0 -0
  384. /package/rules/security/S030_directory_browsing_protection/{README.md → typescript/README.md} +0 -0
  385. /package/rules/security/S030_directory_browsing_protection/{analyzer.js → typescript/analyzer.js} +0 -0
  386. /package/rules/security/S030_directory_browsing_protection/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
  387. /package/rules/security/S030_directory_browsing_protection/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
  388. /package/rules/security/S031_secure_session_cookies/{README.md → typescript/README.md} +0 -0
  389. /package/rules/security/S031_secure_session_cookies/{analyzer.js → typescript/analyzer.js} +0 -0
  390. /package/rules/security/S031_secure_session_cookies/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
  391. /package/rules/security/S032_httponly_session_cookies/{FRAMEWORK_SUPPORT.md → typescript/FRAMEWORK_SUPPORT.md} +0 -0
  392. /package/rules/security/S032_httponly_session_cookies/{README.md → typescript/README.md} +0 -0
  393. /package/rules/security/S032_httponly_session_cookies/{analyzer.js → typescript/analyzer.js} +0 -0
  394. /package/rules/security/S032_httponly_session_cookies/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
  395. /package/rules/security/S032_httponly_session_cookies/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
  396. /package/rules/security/S033_samesite_session_cookies/{README.md → typescript/README.md} +0 -0
  397. /package/rules/security/S033_samesite_session_cookies/{analyzer.js → typescript/analyzer.js} +0 -0
  398. /package/rules/security/S033_samesite_session_cookies/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
  399. /package/rules/security/S033_samesite_session_cookies/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
  400. /package/rules/security/S034_host_prefix_session_cookies/{README.md → typescript/README.md} +0 -0
  401. /package/rules/security/S034_host_prefix_session_cookies/{analyzer.js → typescript/analyzer.js} +0 -0
  402. /package/rules/security/S034_host_prefix_session_cookies/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
  403. /package/rules/security/S034_host_prefix_session_cookies/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
  404. /package/rules/security/S035_path_session_cookies/{README.md → typescript/README.md} +0 -0
  405. /package/rules/security/S035_path_session_cookies/{analyzer.js → typescript/analyzer.js} +0 -0
  406. /package/rules/security/S035_path_session_cookies/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
  407. /package/rules/security/S035_path_session_cookies/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
  408. /package/rules/security/S036_lfi_rfi_protection/{analyzer.js → typescript/analyzer.js} +0 -0
  409. /package/rules/security/S037_cache_headers/{README.md → typescript/README.md} +0 -0
  410. /package/rules/security/S037_cache_headers/{analyzer.js → typescript/analyzer.js} +0 -0
  411. /package/rules/security/S037_cache_headers/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
  412. /package/rules/security/S037_cache_headers/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
  413. /package/rules/security/S038_no_version_headers/{README.md → typescript/README.md} +0 -0
  414. /package/rules/security/S038_no_version_headers/{analyzer.js → typescript/analyzer.js} +0 -0
  415. /package/rules/security/S038_no_version_headers/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
  416. /package/rules/security/S038_no_version_headers/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
  417. /package/rules/security/S039_no_session_tokens_in_url/{README.md → typescript/README.md} +0 -0
  418. /package/rules/security/S039_no_session_tokens_in_url/{analyzer.js → typescript/analyzer.js} +0 -0
  419. /package/rules/security/S039_no_session_tokens_in_url/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
  420. /package/rules/security/S039_no_session_tokens_in_url/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
  421. /package/rules/security/S040_session_fixation_protection/{analyzer.js → typescript/analyzer.js} +0 -0
  422. /package/rules/security/S041_session_token_invalidation/{README.md → typescript/README.md} +0 -0
  423. /package/rules/security/S041_session_token_invalidation/{analyzer.js → typescript/analyzer.js} +0 -0
  424. /package/rules/security/S041_session_token_invalidation/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
  425. /package/rules/security/S041_session_token_invalidation/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
  426. /package/rules/security/S042_require_re_authentication_for_long_lived/{README.md → typescript/README.md} +0 -0
  427. /package/rules/security/S042_require_re_authentication_for_long_lived/{analyzer.js → typescript/analyzer.js} +0 -0
  428. /package/rules/security/S042_require_re_authentication_for_long_lived/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
  429. /package/rules/security/S043_password_changes_invalidate_all_sessions/{README.md → typescript/README.md} +0 -0
  430. /package/rules/security/S043_password_changes_invalidate_all_sessions/{analyzer.js → typescript/analyzer.js} +0 -0
  431. /package/rules/security/S043_password_changes_invalidate_all_sessions/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
  432. /package/rules/security/S044_re_authentication_required/{README.md → typescript/README.md} +0 -0
  433. /package/rules/security/S044_re_authentication_required/{analyzer.js → typescript/analyzer.js} +0 -0
  434. /package/rules/security/S044_re_authentication_required/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
  435. /package/rules/security/S044_re_authentication_required/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
  436. /package/rules/security/S045_brute_force_protection/{README.md → typescript/README.md} +0 -0
  437. /package/rules/security/S045_brute_force_protection/{analyzer.js → typescript/analyzer.js} +0 -0
  438. /package/rules/security/S045_brute_force_protection/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
  439. /package/rules/security/S048_no_current_password_in_reset/{README.md → typescript/README.md} +0 -0
  440. /package/rules/security/S048_no_current_password_in_reset/{analyzer.js → typescript/analyzer.js} +0 -0
  441. /package/rules/security/S049_short_validity_tokens/{analyzer.js → typescript/analyzer.js} +0 -0
  442. /package/rules/security/S049_short_validity_tokens/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
  443. /package/rules/security/S049_short_validity_tokens/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
  444. /package/rules/security/S051_password_length_policy/{analyzer.js → typescript/analyzer.js} +0 -0
  445. /package/rules/security/S052_weak_otp_entropy/{analyzer.js → typescript/analyzer.js} +0 -0
  446. /package/rules/security/S054_no_default_accounts/{README.md → typescript/README.md} +0 -0
  447. /package/rules/security/S054_no_default_accounts/{analyzer.js → typescript/analyzer.js} +0 -0
  448. /package/rules/security/S055_content_type_validation/{README.md → typescript/README.md} +0 -0
  449. /package/rules/security/S055_content_type_validation/{analyzer.js → typescript/analyzer.js} +0 -0
  450. /package/rules/security/S055_content_type_validation/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
  451. /package/rules/security/S056_log_injection_protection/{analyzer.js → typescript/analyzer.js} +0 -0
  452. /package/rules/security/S056_log_injection_protection/{regex-based-analyzer.js → typescript/regex-based-analyzer.js} +0 -0
  453. /package/rules/security/S056_log_injection_protection/{symbol-based-analyzer.js → typescript/symbol-based-analyzer.js} +0 -0
  454. /package/rules/security/S057_utc_logging/{README.md → typescript/README.md} +0 -0
  455. /package/rules/security/S057_utc_logging/{analyzer.js → typescript/analyzer.js} +0 -0
  456. /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
+ };
@@ -101,12 +101,7 @@ class SemanticEngine {
101
101
  /\.(ts|tsx|js|jsx)$/i.test(filePath)
102
102
  );
103
103
 
104
- if (targetFiles) {
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
- if (this.options.verbose) {
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
- console.log(`📁 File discovery: ${targetFiles.length}/${allFiles.length} files selected (memory optimized)`);
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
- // Check for different analyzer files
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
 
@@ -24,15 +24,49 @@ class UploadService {
24
24
  }
25
25
 
26
26
  const uploadResult = await this.executeUploadCommand(filePath, apiUrl, options);
27
-
28
- console.log(chalk.green(`✅ Report uploaded successfully!`));
29
- return {
30
- success: true,
31
- url: apiUrl,
32
- filePath: filePath,
33
- response: uploadResult.response,
34
- statusCode: uploadResult.statusCode
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 = {