@sun-asterisk/sunlint 1.2.1 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. package/CHANGELOG.md +40 -1
  2. package/CONTRIBUTING.md +533 -70
  3. package/README.md +16 -2
  4. package/config/engines/engines-enhanced.json +86 -0
  5. package/config/engines/semantic-config.json +114 -0
  6. package/config/eslint-rule-mapping.json +50 -38
  7. package/config/rule-analysis-strategies.js +18 -2
  8. package/config/rules/enhanced-rules-registry.json +2503 -0
  9. package/config/rules/rules-registry-generated.json +785 -837
  10. package/core/adapters/sunlint-rule-adapter.js +25 -30
  11. package/core/analysis-orchestrator.js +42 -2
  12. package/core/categories.js +52 -0
  13. package/core/category-constants.js +39 -0
  14. package/core/cli-action-handler.js +32 -5
  15. package/core/config-manager.js +111 -0
  16. package/core/config-merger.js +61 -0
  17. package/core/constants/categories.js +168 -0
  18. package/core/constants/defaults.js +165 -0
  19. package/core/constants/engines.js +185 -0
  20. package/core/constants/index.js +30 -0
  21. package/core/constants/rules.js +215 -0
  22. package/core/file-targeting-service.js +128 -7
  23. package/core/interfaces/rule-plugin.interface.js +207 -0
  24. package/core/plugin-manager.js +448 -0
  25. package/core/rule-selection-service.js +42 -15
  26. package/core/semantic-engine.js +560 -0
  27. package/core/semantic-rule-base.js +433 -0
  28. package/core/unified-rule-registry.js +484 -0
  29. package/docs/CONSTANTS-ARCHITECTURE.md +288 -0
  30. package/engines/core/base-engine.js +249 -0
  31. package/engines/engine-factory.js +275 -0
  32. package/engines/eslint-engine.js +180 -30
  33. package/engines/heuristic-engine.js +513 -56
  34. package/integrations/eslint/plugin/index.js +27 -27
  35. package/package.json +11 -6
  36. package/rules/README.md +252 -0
  37. package/rules/common/C002_no_duplicate_code/analyzer.js +65 -0
  38. package/rules/common/C002_no_duplicate_code/config.json +23 -0
  39. package/rules/common/C003_no_vague_abbreviations/analyzer.js +418 -0
  40. package/rules/common/C003_no_vague_abbreviations/config.json +35 -0
  41. package/rules/common/C006_function_naming/analyzer.js +504 -0
  42. package/rules/common/C006_function_naming/config.json +86 -0
  43. package/rules/common/C006_function_naming/smart-analyzer.js +503 -0
  44. package/rules/common/C010_limit_block_nesting/analyzer.js +389 -0
  45. package/rules/common/C012_command_query_separation/analyzer.js +481 -0
  46. package/rules/common/C012_command_query_separation/ast-analyzer.js +495 -0
  47. package/rules/common/C013_no_dead_code/analyzer.js +206 -0
  48. package/rules/common/C014_dependency_injection/analyzer.js +338 -0
  49. package/rules/common/C017_constructor_logic/analyzer.js +314 -0
  50. package/rules/common/C019_log_level_usage/analyzer.js +362 -0
  51. package/rules/common/C019_log_level_usage/config.json +121 -0
  52. package/rules/common/C029_catch_block_logging/analyzer-smart-pipeline.js +755 -0
  53. package/rules/common/C029_catch_block_logging/analyzer.js +141 -0
  54. package/rules/common/C029_catch_block_logging/config.json +59 -0
  55. package/rules/common/C031_validation_separation/analyzer.js +186 -0
  56. package/rules/common/C041_no_sensitive_hardcode/analyzer.js +292 -0
  57. package/rules/common/C041_no_sensitive_hardcode/ast-analyzer.js +296 -0
  58. package/rules/common/C042_boolean_name_prefix/analyzer.js +300 -0
  59. package/rules/common/C043_no_console_or_print/analyzer.js +431 -0
  60. package/rules/common/C047_no_duplicate_retry_logic/analyzer.js +590 -0
  61. package/rules/common/C047_no_duplicate_retry_logic/c047-semantic-rule.js +278 -0
  62. package/rules/common/C047_no_duplicate_retry_logic/symbol-analyzer-enhanced.js +968 -0
  63. package/rules/common/C047_no_duplicate_retry_logic/symbol-config.json +71 -0
  64. package/rules/common/C075_explicit_return_types/analyzer.js +103 -0
  65. package/rules/common/C076_single_test_behavior/analyzer.js +121 -0
  66. package/rules/docs/C002_no_duplicate_code.md +57 -0
  67. package/rules/docs/C031_validation_separation.md +72 -0
  68. package/rules/index.js +162 -0
  69. package/rules/migration/converter.js +385 -0
  70. package/rules/migration/mapping.json +164 -0
  71. package/rules/parser/constants.js +31 -0
  72. package/rules/parser/file-config.js +80 -0
  73. package/rules/parser/rule-parser-simple.js +305 -0
  74. package/rules/parser/rule-parser.js +527 -0
  75. package/rules/security/S015_insecure_tls_certificate/analyzer.js +150 -0
  76. package/rules/security/S015_insecure_tls_certificate/ast-analyzer.js +237 -0
  77. package/rules/security/S023_no_json_injection/analyzer.js +278 -0
  78. package/rules/security/S023_no_json_injection/ast-analyzer.js +359 -0
  79. package/rules/security/S026_json_schema_validation/analyzer.js +251 -0
  80. package/rules/security/S026_json_schema_validation/config.json +27 -0
  81. package/rules/security/S027_no_hardcoded_secrets/analyzer.js +436 -0
  82. package/rules/security/S027_no_hardcoded_secrets/config.json +29 -0
  83. package/rules/security/S029_csrf_protection/analyzer.js +330 -0
  84. package/rules/tests/C002_no_duplicate_code.test.js +50 -0
  85. package/rules/utils/ast-utils.js +191 -0
  86. package/rules/utils/base-analyzer.js +98 -0
  87. package/rules/utils/pattern-matchers.js +239 -0
  88. package/rules/utils/rule-helpers.js +264 -0
  89. package/rules/utils/severity-constants.js +93 -0
  90. package/scripts/category-manager.js +150 -0
  91. package/scripts/generate-rules-registry.js +88 -0
  92. package/scripts/generate_insights.js +188 -0
  93. package/scripts/migrate-rule-registry.js +157 -0
  94. package/scripts/validate-system.js +48 -0
  95. package/.sunlint.json +0 -35
  96. package/config/README.md +0 -88
  97. package/config/engines/eslint-rule-mapping.json +0 -74
  98. package/config/testing/test-s005-working.ts +0 -22
  99. package/engines/tree-sitter-parser.js +0 -0
  100. package/engines/universal-ast-engine.js +0 -0
  101. package/scripts/merge-reports.js +0 -424
  102. package/scripts/test-scripts/README.md +0 -22
  103. package/scripts/test-scripts/test-c041-comparison.js +0 -114
  104. package/scripts/test-scripts/test-c041-eslint.js +0 -67
  105. package/scripts/test-scripts/test-eslint-rules.js +0 -146
  106. package/scripts/test-scripts/test-real-world.js +0 -44
  107. package/scripts/test-scripts/test-rules-on-real-projects.js +0 -86
  108. /package/{config/schemas/sunlint-schema.json → rules/universal/C010/generic.js} +0 -0
  109. /package/{core/multi-rule-runner.js → rules/universal/C010/tree-sitter-analyzer.js} +0 -0
@@ -0,0 +1,168 @@
1
+ /**
2
+ * SunLint Category Constants
3
+ * Single source of truth for all category-principle mappings
4
+ * Used by: sunlint-rule-adapter.js, plugin-manager.js, custom rules, etc.
5
+ */
6
+
7
+ /**
8
+ * Official SunLint Principles (constant values)
9
+ * These should match exactly with principles used in origin-rules
10
+ */
11
+ const SUNLINT_PRINCIPLES = {
12
+ CODE_QUALITY: 'CODE_QUALITY',
13
+ DESIGN_PATTERNS: 'DESIGN_PATTERNS',
14
+ INTEGRATION: 'INTEGRATION',
15
+ MAINTAINABILITY: 'MAINTAINABILITY',
16
+ PERFORMANCE: 'PERFORMANCE',
17
+ RELIABILITY: 'RELIABILITY',
18
+ SECURITY: 'SECURITY',
19
+ TESTABILITY: 'TESTABILITY',
20
+ USABILITY: 'USABILITY'
21
+ };
22
+
23
+ /**
24
+ * Category to Principle Mapping
25
+ * Single source of truth - used across all components
26
+ */
27
+ const CATEGORY_PRINCIPLE_MAP = {
28
+ 'security': [SUNLINT_PRINCIPLES.SECURITY],
29
+ 'quality': [SUNLINT_PRINCIPLES.CODE_QUALITY],
30
+ 'performance': [SUNLINT_PRINCIPLES.PERFORMANCE],
31
+ 'maintainability': [SUNLINT_PRINCIPLES.MAINTAINABILITY],
32
+ 'testability': [SUNLINT_PRINCIPLES.TESTABILITY],
33
+ 'reliability': [SUNLINT_PRINCIPLES.RELIABILITY],
34
+ 'design': [SUNLINT_PRINCIPLES.DESIGN_PATTERNS],
35
+ 'integration': [SUNLINT_PRINCIPLES.INTEGRATION],
36
+ 'usability': [SUNLINT_PRINCIPLES.USABILITY]
37
+ };
38
+
39
+ /**
40
+ * Human-readable category descriptions
41
+ */
42
+ const CATEGORY_DESCRIPTIONS = {
43
+ 'quality': 'Code quality and best practices',
44
+ 'design': 'Design patterns and architectural principles',
45
+ 'integration': 'Integration and API design',
46
+ 'maintainability': 'Code maintainability and readability',
47
+ 'performance': 'Performance optimization and efficiency',
48
+ 'reliability': 'Error handling and code reliability',
49
+ 'security': 'Security-related rules to prevent vulnerabilities',
50
+ 'testability': 'Testing and test-driven development',
51
+ 'usability': 'User experience and interface guidelines'
52
+ };
53
+
54
+ /**
55
+ * Get all valid categories
56
+ * @returns {Array<string>} Array of category names
57
+ */
58
+ function getValidCategories() {
59
+ return Object.keys(CATEGORY_PRINCIPLE_MAP);
60
+ }
61
+
62
+ /**
63
+ * Get principles for a category
64
+ * @param {string} category - Category name
65
+ * @returns {Array<string>} Array of principles
66
+ */
67
+ function getCategoryPrinciples(category) {
68
+ return CATEGORY_PRINCIPLE_MAP[category?.toLowerCase()] || [];
69
+ }
70
+
71
+ /**
72
+ * Validate if a category is valid
73
+ * @param {string} category - Category to validate
74
+ * @returns {boolean} True if valid
75
+ */
76
+ function isValidCategory(category) {
77
+ return getValidCategories().includes(category?.toLowerCase());
78
+ }
79
+
80
+ /**
81
+ * Get category description
82
+ * @param {string} category - Category name
83
+ * @returns {string} Category description
84
+ */
85
+ function getCategoryDescription(category) {
86
+ return CATEGORY_DESCRIPTIONS[category?.toLowerCase()] || 'Unknown category';
87
+ }
88
+
89
+ /**
90
+ * Get default category (fallback)
91
+ * @returns {string} Default category name
92
+ */
93
+ function getDefaultCategory() {
94
+ return 'quality'; // CODE_QUALITY principle
95
+ }
96
+
97
+ /**
98
+ * Normalize category name (lowercase, validate)
99
+ * @param {string} category - Category to normalize
100
+ * @returns {string} Normalized category or default
101
+ */
102
+ function normalizeCategory(category) {
103
+ if (!category) return getDefaultCategory();
104
+
105
+ const normalized = category.toLowerCase();
106
+ return isValidCategory(normalized) ? normalized : getDefaultCategory();
107
+ }
108
+
109
+ /**
110
+ * Get category for a principle (reverse lookup)
111
+ * @param {string} principle - Principle name
112
+ * @returns {string|null} Category name or null
113
+ */
114
+ function getCategoryForPrinciple(principle) {
115
+ for (const [category, principles] of Object.entries(CATEGORY_PRINCIPLE_MAP)) {
116
+ if (principles.includes(principle)) {
117
+ return category;
118
+ }
119
+ }
120
+ return null;
121
+ }
122
+
123
+ /**
124
+ * Add new category-principle mapping (for future extensibility)
125
+ * @param {string} category - Category name
126
+ * @param {Array<string>} principles - Array of principles
127
+ * @param {string} description - Category description
128
+ */
129
+ function addCategoryMapping(category, principles, description) {
130
+ const normalizedCategory = category.toLowerCase();
131
+ CATEGORY_PRINCIPLE_MAP[normalizedCategory] = principles;
132
+ CATEGORY_DESCRIPTIONS[normalizedCategory] = description;
133
+ }
134
+
135
+ /**
136
+ * Get category statistics
137
+ * @returns {Object} Category statistics
138
+ */
139
+ function getCategoryStats() {
140
+ const categories = getValidCategories();
141
+ const principleCount = Object.values(CATEGORY_PRINCIPLE_MAP)
142
+ .flat().length;
143
+
144
+ return {
145
+ totalCategories: categories.length,
146
+ totalPrinciples: principleCount,
147
+ categories: categories,
148
+ mapping: CATEGORY_PRINCIPLE_MAP
149
+ };
150
+ }
151
+
152
+ module.exports = {
153
+ // Constants
154
+ SUNLINT_PRINCIPLES,
155
+ CATEGORY_PRINCIPLE_MAP,
156
+ CATEGORY_DESCRIPTIONS,
157
+
158
+ // Utility functions
159
+ getValidCategories,
160
+ getCategoryPrinciples,
161
+ isValidCategory,
162
+ getCategoryDescription,
163
+ getDefaultCategory,
164
+ normalizeCategory,
165
+ getCategoryForPrinciple,
166
+ addCategoryMapping,
167
+ getCategoryStats
168
+ };
@@ -0,0 +1,165 @@
1
+ /**
2
+ * SunLint Default Values and Configuration Constants
3
+ * Centralized location for all default values used across the system
4
+ */
5
+
6
+ /**
7
+ * Default rule sets for different scenarios
8
+ */
9
+ const DEFAULT_RULE_SETS = {
10
+ // Minimal set for quick checks
11
+ MINIMAL: ['C006', 'C019'],
12
+
13
+ // Essential rules for any project
14
+ ESSENTIAL: [
15
+ 'C001', 'C002', 'C003', 'C004', 'C005', 'C006',
16
+ 'C007', 'C008', 'C009', 'C010', 'C019'
17
+ ],
18
+
19
+ // Security-focused rules
20
+ SECURITY: [
21
+ 'S001', 'S002', 'S003', 'S004', 'S005',
22
+ 'S010', 'S015', 'S020', 'S025'
23
+ ],
24
+
25
+ // Performance-focused rules
26
+ PERFORMANCE: [
27
+ 'C015', 'C020', 'C025', 'C030',
28
+ 'T010', 'T015', 'T020'
29
+ ]
30
+ };
31
+
32
+ /**
33
+ * Default severity levels
34
+ */
35
+ const DEFAULT_SEVERITIES = {
36
+ ERROR: 'error',
37
+ WARNING: 'warning',
38
+ INFO: 'info',
39
+ HINT: 'hint'
40
+ };
41
+
42
+ /**
43
+ * Default configuration values
44
+ */
45
+ const DEFAULT_CONFIG = {
46
+ // Analysis options
47
+ verbose: false,
48
+ useRegistry: true,
49
+ skipTests: false,
50
+ includeTests: false,
51
+
52
+ // File targeting
53
+ maxFileSize: 1024 * 1024, // 1MB
54
+ includePatterns: ['**/*.{js,ts,jsx,tsx,java,kt,dart,swift}'],
55
+ excludePatterns: [
56
+ '**/node_modules/**',
57
+ '**/dist/**',
58
+ '**/build/**',
59
+ '**/.git/**',
60
+ '**/coverage/**'
61
+ ],
62
+
63
+ // Rule selection
64
+ ruleSet: 'ESSENTIAL',
65
+ categories: [],
66
+ excludeRules: [],
67
+
68
+ // Output options
69
+ outputFormat: 'console',
70
+ reportFile: null,
71
+ showStats: true
72
+ };
73
+
74
+ /**
75
+ * Default timeout values (in milliseconds)
76
+ */
77
+ const DEFAULT_TIMEOUTS = {
78
+ RULE_EXECUTION: 30000, // 30 seconds per rule
79
+ FILE_ANALYSIS: 5000, // 5 seconds per file
80
+ ENGINE_INITIALIZATION: 10000, // 10 seconds for engine init
81
+ TOTAL_ANALYSIS: 300000 // 5 minutes total
82
+ };
83
+
84
+ /**
85
+ * Default file size limits
86
+ */
87
+ const DEFAULT_LIMITS = {
88
+ MAX_FILE_SIZE: 1024 * 1024, // 1MB
89
+ MAX_FILES_PER_BATCH: 100, // Process 100 files at once
90
+ MAX_CONCURRENT_RULES: 5, // Run 5 rules concurrently
91
+ MAX_OUTPUT_LINES: 1000 // Limit output to 1000 lines
92
+ };
93
+
94
+ /**
95
+ * Default language extensions mapping
96
+ */
97
+ const DEFAULT_LANGUAGE_EXTENSIONS = {
98
+ javascript: ['.js', '.jsx', '.mjs'],
99
+ typescript: ['.ts', '.tsx'],
100
+ java: ['.java'],
101
+ kotlin: ['.kt', '.kts'],
102
+ dart: ['.dart'],
103
+ swift: ['.swift'],
104
+ python: ['.py'],
105
+ go: ['.go'],
106
+ rust: ['.rs'],
107
+ php: ['.php']
108
+ };
109
+
110
+ /**
111
+ * Get default rule set by name
112
+ * @param {string} setName - Name of the rule set
113
+ * @returns {Array<string>} Array of rule IDs
114
+ */
115
+ function getDefaultRuleSet(setName = 'ESSENTIAL') {
116
+ return DEFAULT_RULE_SETS[setName.toUpperCase()] || DEFAULT_RULE_SETS.ESSENTIAL;
117
+ }
118
+
119
+ /**
120
+ * Get default configuration with overrides
121
+ * @param {Object} overrides - Configuration overrides
122
+ * @returns {Object} Merged configuration
123
+ */
124
+ function getDefaultConfig(overrides = {}) {
125
+ return {
126
+ ...DEFAULT_CONFIG,
127
+ ...overrides
128
+ };
129
+ }
130
+
131
+ /**
132
+ * Get file extensions for a language
133
+ * @param {string} language - Programming language
134
+ * @returns {Array<string>} Array of file extensions
135
+ */
136
+ function getLanguageExtensions(language) {
137
+ return DEFAULT_LANGUAGE_EXTENSIONS[language?.toLowerCase()] || [];
138
+ }
139
+
140
+ /**
141
+ * Check if file size is within limits
142
+ * @param {number} fileSize - File size in bytes
143
+ * @returns {boolean} True if within limits
144
+ */
145
+ function isFileSizeValid(fileSize) {
146
+ return fileSize <= DEFAULT_LIMITS.MAX_FILE_SIZE;
147
+ }
148
+
149
+ module.exports = {
150
+ // Rule sets
151
+ DEFAULT_RULE_SETS,
152
+
153
+ // Configuration
154
+ DEFAULT_CONFIG,
155
+ DEFAULT_SEVERITIES,
156
+ DEFAULT_TIMEOUTS,
157
+ DEFAULT_LIMITS,
158
+ DEFAULT_LANGUAGE_EXTENSIONS,
159
+
160
+ // Utility functions
161
+ getDefaultRuleSet,
162
+ getDefaultConfig,
163
+ getLanguageExtensions,
164
+ isFileSizeValid
165
+ };
@@ -0,0 +1,185 @@
1
+ /**
2
+ * SunLint Engine Constants
3
+ * Constants related to analysis engines and their configurations
4
+ */
5
+
6
+ /**
7
+ * Supported analysis engines
8
+ */
9
+ const SUPPORTED_ENGINES = {
10
+ HEURISTIC: 'heuristic',
11
+ ESLINT: 'eslint',
12
+ OPENAI: 'openai',
13
+ TREE_SITTER: 'tree-sitter',
14
+ UNIVERSAL_AST: 'universal-ast'
15
+ };
16
+
17
+ /**
18
+ * Engine capabilities and supported languages
19
+ */
20
+ const ENGINE_CAPABILITIES = {
21
+ [SUPPORTED_ENGINES.HEURISTIC]: {
22
+ languages: ['javascript', 'typescript', 'java', 'kotlin', 'dart', 'swift', 'python'],
23
+ features: ['pattern-matching', 'regex-analysis', 'text-based'],
24
+ priority: 1
25
+ },
26
+
27
+ [SUPPORTED_ENGINES.ESLINT]: {
28
+ languages: ['javascript', 'typescript'],
29
+ features: ['ast-analysis', 'rule-plugins', 'fixable'],
30
+ priority: 2
31
+ },
32
+
33
+ [SUPPORTED_ENGINES.OPENAI]: {
34
+ languages: ['javascript', 'typescript', 'java', 'kotlin', 'dart', 'swift', 'python'],
35
+ features: ['ai-analysis', 'context-aware', 'natural-language'],
36
+ priority: 3
37
+ },
38
+
39
+ [SUPPORTED_ENGINES.TREE_SITTER]: {
40
+ languages: ['javascript', 'typescript', 'java', 'kotlin', 'python', 'go', 'rust'],
41
+ features: ['ast-parsing', 'syntax-tree', 'language-agnostic'],
42
+ priority: 2
43
+ },
44
+
45
+ [SUPPORTED_ENGINES.UNIVERSAL_AST]: {
46
+ languages: ['javascript', 'typescript', 'java', 'kotlin', 'dart', 'swift'],
47
+ features: ['universal-ast', 'cross-language', 'normalized-tree'],
48
+ priority: 2
49
+ }
50
+ };
51
+
52
+ /**
53
+ * Engine execution modes
54
+ */
55
+ const ENGINE_MODES = {
56
+ SEQUENTIAL: 'sequential', // Run engines one by one
57
+ PARALLEL: 'parallel', // Run engines in parallel
58
+ HYBRID: 'hybrid', // Smart combination
59
+ FALLBACK: 'fallback' // Use fallback engine on failure
60
+ };
61
+
62
+ /**
63
+ * Engine performance configurations
64
+ */
65
+ const ENGINE_PERFORMANCE = {
66
+ [SUPPORTED_ENGINES.HEURISTIC]: {
67
+ maxConcurrentFiles: 50,
68
+ averageTimePerFile: 100, // milliseconds
69
+ memoryUsage: 'low'
70
+ },
71
+
72
+ [SUPPORTED_ENGINES.ESLINT]: {
73
+ maxConcurrentFiles: 20,
74
+ averageTimePerFile: 500, // milliseconds
75
+ memoryUsage: 'medium'
76
+ },
77
+
78
+ [SUPPORTED_ENGINES.OPENAI]: {
79
+ maxConcurrentFiles: 5,
80
+ averageTimePerFile: 2000, // milliseconds
81
+ memoryUsage: 'low',
82
+ rateLimited: true
83
+ },
84
+
85
+ [SUPPORTED_ENGINES.TREE_SITTER]: {
86
+ maxConcurrentFiles: 30,
87
+ averageTimePerFile: 300, // milliseconds
88
+ memoryUsage: 'medium'
89
+ },
90
+
91
+ [SUPPORTED_ENGINES.UNIVERSAL_AST]: {
92
+ maxConcurrentFiles: 25,
93
+ averageTimePerFile: 400, // milliseconds
94
+ memoryUsage: 'medium'
95
+ }
96
+ };
97
+
98
+ /**
99
+ * Default engine selection strategy
100
+ */
101
+ const DEFAULT_ENGINE_STRATEGY = {
102
+ mode: ENGINE_MODES.HYBRID,
103
+ primaryEngine: SUPPORTED_ENGINES.HEURISTIC,
104
+ fallbackEngine: SUPPORTED_ENGINES.HEURISTIC,
105
+ enableParallel: false,
106
+ maxEngines: 2
107
+ };
108
+
109
+ /**
110
+ * Get supported languages for an engine
111
+ * @param {string} engineName - Name of the engine
112
+ * @returns {Array<string>} Supported languages
113
+ */
114
+ function getEngineLanguages(engineName) {
115
+ const engine = ENGINE_CAPABILITIES[engineName];
116
+ return engine ? engine.languages : [];
117
+ }
118
+
119
+ /**
120
+ * Get engines that support a specific language
121
+ * @param {string} language - Programming language
122
+ * @returns {Array<string>} Engine names that support the language
123
+ */
124
+ function getEnginesForLanguage(language) {
125
+ const supportedEngines = [];
126
+
127
+ for (const [engineName, capabilities] of Object.entries(ENGINE_CAPABILITIES)) {
128
+ if (capabilities.languages.includes(language)) {
129
+ supportedEngines.push({
130
+ name: engineName,
131
+ priority: capabilities.priority,
132
+ features: capabilities.features
133
+ });
134
+ }
135
+ }
136
+
137
+ // Sort by priority (lower number = higher priority)
138
+ return supportedEngines.sort((a, b) => a.priority - b.priority);
139
+ }
140
+
141
+ /**
142
+ * Get recommended engine for a language
143
+ * @param {string} language - Programming language
144
+ * @returns {string} Recommended engine name
145
+ */
146
+ function getRecommendedEngine(language) {
147
+ const engines = getEnginesForLanguage(language);
148
+ return engines.length > 0 ? engines[0].name : SUPPORTED_ENGINES.HEURISTIC;
149
+ }
150
+
151
+ /**
152
+ * Check if engine supports a language
153
+ * @param {string} engineName - Engine name
154
+ * @param {string} language - Programming language
155
+ * @returns {boolean} True if supported
156
+ */
157
+ function isLanguageSupported(engineName, language) {
158
+ const languages = getEngineLanguages(engineName);
159
+ return languages.includes(language);
160
+ }
161
+
162
+ /**
163
+ * Get engine performance configuration
164
+ * @param {string} engineName - Engine name
165
+ * @returns {Object} Performance configuration
166
+ */
167
+ function getEnginePerformance(engineName) {
168
+ return ENGINE_PERFORMANCE[engineName] || ENGINE_PERFORMANCE[SUPPORTED_ENGINES.HEURISTIC];
169
+ }
170
+
171
+ module.exports = {
172
+ // Engine constants
173
+ SUPPORTED_ENGINES,
174
+ ENGINE_CAPABILITIES,
175
+ ENGINE_MODES,
176
+ ENGINE_PERFORMANCE,
177
+ DEFAULT_ENGINE_STRATEGY,
178
+
179
+ // Utility functions
180
+ getEngineLanguages,
181
+ getEnginesForLanguage,
182
+ getRecommendedEngine,
183
+ isLanguageSupported,
184
+ getEnginePerformance
185
+ };
@@ -0,0 +1,30 @@
1
+ /**
2
+ * SunLint Constants - Barrel Export
3
+ * Centralized access point for all constants
4
+ */
5
+
6
+ // Re-export all constants from sub-modules
7
+ const categories = require('./categories');
8
+ const defaults = require('./defaults');
9
+ const engines = require('./engines');
10
+ const rules = require('./rules');
11
+
12
+ module.exports = {
13
+ // Categories & Principles
14
+ ...categories,
15
+
16
+ // Default values & configurations
17
+ ...defaults,
18
+
19
+ // Engine-related constants
20
+ ...engines,
21
+
22
+ // Rule-related constants
23
+ ...rules,
24
+
25
+ // Grouped exports for specific use cases
26
+ categories,
27
+ defaults,
28
+ engines,
29
+ rules
30
+ };