@sun-asterisk/sunlint 1.2.2 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. package/CHANGELOG.md +107 -1
  2. package/CONTRIBUTING.md +1654 -66
  3. package/README.md +19 -6
  4. package/config/ci-cd.json +54 -0
  5. package/config/development.json +56 -0
  6. package/config/engines/engines-enhanced.json +86 -0
  7. package/config/engines/semantic-config.json +114 -0
  8. package/config/eslint-rule-mapping.json +50 -38
  9. package/config/large-project.json +143 -0
  10. package/config/presets/all.json +0 -1
  11. package/config/release.json +70 -0
  12. package/config/rule-analysis-strategies.js +23 -4
  13. package/config/rules/S027-categories.json +122 -0
  14. package/config/rules/enhanced-rules-registry.json +2564 -0
  15. package/config/rules/rules-registry-generated.json +785 -837
  16. package/config/rules/rules-registry.json +13 -1
  17. package/core/adapters/sunlint-rule-adapter.js +25 -30
  18. package/core/analysis-orchestrator.js +42 -2
  19. package/core/categories.js +52 -0
  20. package/core/category-constants.js +39 -0
  21. package/core/cli-action-handler.js +53 -32
  22. package/core/cli-program.js +11 -3
  23. package/core/config-manager.js +111 -0
  24. package/core/config-merger.js +88 -0
  25. package/core/constants/categories.js +168 -0
  26. package/core/constants/defaults.js +165 -0
  27. package/core/constants/engines.js +185 -0
  28. package/core/constants/index.js +30 -0
  29. package/core/constants/rules.js +215 -0
  30. package/core/enhanced-rules-registry.js +3 -3
  31. package/core/file-targeting-service.js +128 -7
  32. package/core/interfaces/rule-plugin.interface.js +207 -0
  33. package/core/plugin-manager.js +448 -0
  34. package/core/rule-selection-service.js +42 -15
  35. package/core/semantic-engine.js +658 -0
  36. package/core/semantic-rule-base.js +433 -0
  37. package/core/unified-rule-registry.js +484 -0
  38. package/docs/COMMAND-EXAMPLES.md +134 -0
  39. package/docs/CONSTANTS-ARCHITECTURE.md +288 -0
  40. package/docs/LARGE-PROJECT-GUIDE.md +324 -0
  41. package/engines/core/base-engine.js +249 -0
  42. package/engines/engine-factory.js +275 -0
  43. package/engines/eslint-engine.js +171 -19
  44. package/engines/heuristic-engine.js +569 -78
  45. package/integrations/eslint/plugin/index.js +26 -28
  46. package/origin-rules/common-en.md +8 -8
  47. package/package.json +10 -6
  48. package/rules/common/C003_no_vague_abbreviations/analyzer.js +1 -1
  49. package/rules/common/C017_constructor_logic/analyzer.js +254 -17
  50. package/rules/common/C017_constructor_logic/semantic-analyzer.js +340 -0
  51. package/rules/common/C029_catch_block_logging/analyzer.js +17 -5
  52. package/rules/common/C033_separate_service_repository/README.md +78 -0
  53. package/rules/common/C033_separate_service_repository/analyzer.js +160 -0
  54. package/rules/common/C033_separate_service_repository/config.json +50 -0
  55. package/rules/common/C033_separate_service_repository/regex-based-analyzer.js +585 -0
  56. package/rules/common/C033_separate_service_repository/symbol-based-analyzer.js +368 -0
  57. package/rules/common/C035_error_logging_context/STRATEGY.md +99 -0
  58. package/rules/common/C035_error_logging_context/analyzer.js +230 -0
  59. package/rules/common/C035_error_logging_context/config.json +54 -0
  60. package/rules/common/C035_error_logging_context/regex-based-analyzer.js +299 -0
  61. package/rules/common/C035_error_logging_context/symbol-based-analyzer.js +454 -0
  62. package/rules/common/C040_centralized_validation/analyzer.js +165 -0
  63. package/rules/common/C040_centralized_validation/config.json +46 -0
  64. package/rules/common/C040_centralized_validation/regex-based-analyzer.js +243 -0
  65. package/rules/common/C040_centralized_validation/symbol-based-analyzer.js +416 -0
  66. package/rules/common/C047_no_duplicate_retry_logic/c047-semantic-rule.js +278 -0
  67. package/rules/common/C047_no_duplicate_retry_logic/symbol-analyzer-enhanced.js +968 -0
  68. package/rules/common/C047_no_duplicate_retry_logic/symbol-config.json +71 -0
  69. package/rules/common/{C076_single_test_behavior → C072_single_test_behavior}/analyzer.js +6 -6
  70. package/rules/common/C076_explicit_function_types/README.md +30 -0
  71. package/rules/common/C076_explicit_function_types/analyzer.js +172 -0
  72. package/rules/common/C076_explicit_function_types/config.json +15 -0
  73. package/rules/common/C076_explicit_function_types/semantic-analyzer.js +341 -0
  74. package/rules/index.js +8 -0
  75. package/rules/parser/rule-parser.js +13 -2
  76. package/rules/security/S005_no_origin_auth/README.md +226 -0
  77. package/rules/security/S005_no_origin_auth/analyzer.js +184 -0
  78. package/rules/security/S005_no_origin_auth/ast-analyzer.js +406 -0
  79. package/rules/security/S005_no_origin_auth/config.json +85 -0
  80. package/rules/security/S006_no_plaintext_recovery_codes/README.md +139 -0
  81. package/rules/security/S006_no_plaintext_recovery_codes/analyzer.js +306 -0
  82. package/rules/security/S006_no_plaintext_recovery_codes/config.json +48 -0
  83. package/rules/security/S007_no_plaintext_otp/README.md +198 -0
  84. package/rules/security/S007_no_plaintext_otp/analyzer.js +406 -0
  85. package/rules/security/S007_no_plaintext_otp/config.json +79 -0
  86. package/rules/security/S007_no_plaintext_otp/semantic-analyzer.js +609 -0
  87. package/rules/security/S007_no_plaintext_otp/semantic-config.json +195 -0
  88. package/rules/security/S007_no_plaintext_otp/semantic-wrapper.js +280 -0
  89. package/rules/security/S027_no_hardcoded_secrets/analyzer.js +180 -366
  90. package/rules/security/S027_no_hardcoded_secrets/categories.json +153 -0
  91. package/rules/security/S027_no_hardcoded_secrets/categorized-analyzer.js +250 -0
  92. package/scripts/category-manager.js +150 -0
  93. package/scripts/generate-rules-registry.js +88 -0
  94. package/scripts/migrate-rule-registry.js +157 -0
  95. package/scripts/prepare-release.sh +1 -1
  96. package/scripts/validate-system.js +48 -0
  97. package/.sunlint.json +0 -35
  98. package/config/README.md +0 -88
  99. package/config/engines/eslint-rule-mapping.json +0 -74
  100. package/config/schemas/sunlint-schema.json +0 -0
  101. package/config/testing/test-s005-working.ts +0 -22
  102. package/core/multi-rule-runner.js +0 -0
  103. package/docs/ESLINT-INTEGRATION-STRATEGY.md +0 -392
  104. package/docs/FUTURE_PACKAGES.md +0 -83
  105. package/docs/HEURISTIC_VS_AI.md +0 -113
  106. package/docs/PRODUCTION_DEPLOYMENT_ANALYSIS.md +0 -112
  107. package/docs/PRODUCTION_SIZE_IMPACT.md +0 -183
  108. package/docs/RELEASE_GUIDE.md +0 -230
  109. package/docs/STANDARDIZED-CATEGORY-FILTERING.md +0 -156
  110. package/engines/tree-sitter-parser.js +0 -0
  111. package/engines/universal-ast-engine.js +0 -0
  112. package/integrations/eslint/plugin/rules/common/c076-single-behavior-per-test.js +0 -254
  113. package/rules/common/C029_catch_block_logging/analyzer-backup.js +0 -426
  114. package/rules/common/C029_catch_block_logging/analyzer-fixed.js +0 -130
  115. package/rules/common/C029_catch_block_logging/analyzer-multi-tech.js +0 -487
  116. package/rules/common/C029_catch_block_logging/analyzer-simple.js +0 -110
  117. package/rules/common/C029_catch_block_logging/ast-analyzer-backup.js +0 -441
  118. package/rules/common/C029_catch_block_logging/ast-analyzer-new.js +0 -127
  119. package/rules/common/C029_catch_block_logging/ast-analyzer.js +0 -133
  120. package/rules/common/C029_catch_block_logging/cfg-analyzer.js +0 -408
  121. package/rules/common/C029_catch_block_logging/dataflow-analyzer.js +0 -454
  122. package/rules/common/C029_catch_block_logging/multi-language-ast-engine.js +0 -700
  123. package/rules/common/C029_catch_block_logging/pattern-learning-analyzer.js +0 -568
  124. package/rules/common/C029_catch_block_logging/semantic-analyzer.js +0 -459
@@ -1,3 +1,6 @@
1
+ const { minimatch } = require('minimatch');
2
+ const chalk = require('chalk');
3
+
1
4
  /**
2
5
  * Handles configuration merging and CLI overrides
3
6
  * Rule C005: Single responsibility - chỉ merge và override config
@@ -89,6 +92,11 @@ class ConfigMerger {
89
92
  // Performance overrides
90
93
  overrides.performance = this.applyPerformanceOverrides(overrides.performance, options);
91
94
 
95
+ // Auto-expand include patterns if input doesn't match any existing patterns
96
+ const expandedOverrides = this.autoExpandIncludePatterns(overrides, options);
97
+ // Copy expanded properties back to overrides
98
+ Object.assign(overrides, expandedOverrides);
99
+
92
100
  return overrides;
93
101
  }
94
102
 
@@ -161,6 +169,86 @@ class ConfigMerger {
161
169
  return updatedConfig;
162
170
  }
163
171
 
172
+ /**
173
+ * Rule C006: autoExpandIncludePatterns - verb-noun naming
174
+ * Rule C005: Single responsibility - auto-expand include patterns for input paths
175
+ */
176
+ autoExpandIncludePatterns(config, options) {
177
+ if (!options.input) {
178
+ return config;
179
+ }
180
+
181
+ const result = { ...config };
182
+ const inputPaths = Array.isArray(options.input) ? options.input : [options.input];
183
+ const currentInclude = result.include || [];
184
+
185
+ console.log(chalk.gray(`🔍 AUTO-EXPANSION: Checking input paths: ${inputPaths.join(', ')}`));
186
+ console.log(chalk.gray(`🔍 AUTO-EXPANSION: Current include patterns: ${currentInclude.join(', ')}`));
187
+
188
+ let needsExpansion = false;
189
+ for (const inputPath of inputPaths) {
190
+ const matchesExisting = currentInclude.some(pattern => {
191
+ const match1 = minimatch(inputPath, pattern);
192
+ const match2 = minimatch(inputPath + '/**', pattern);
193
+ const match3 = minimatch('**/' + inputPath, pattern);
194
+ const match4 = minimatch('**/' + inputPath + '/**', pattern);
195
+
196
+ console.log(chalk.gray(` AUTO-EXPANSION: ${inputPath} vs ${pattern}: ${match1 || match2 || match3 || match4}`));
197
+
198
+ return match1 || match2 || match3 || match4;
199
+ });
200
+
201
+ if (!matchesExisting) {
202
+ needsExpansion = true;
203
+ console.log(chalk.gray(` 🔄 AUTO-EXPANSION: ${inputPath} needs expansion`));
204
+ break;
205
+ }
206
+ }
207
+
208
+ if (needsExpansion) {
209
+ // Add flexible patterns for input paths
210
+ const expandedInclude = [...currentInclude];
211
+ for (const inputPath of inputPaths) {
212
+ // Check if inputPath is a file or directory
213
+ const fs = require('fs');
214
+ const path = require('path');
215
+
216
+ try {
217
+ const resolvedPath = path.resolve(inputPath);
218
+ if (fs.existsSync(resolvedPath)) {
219
+ const stat = fs.statSync(resolvedPath);
220
+ if (stat.isFile()) {
221
+ // For files, add the exact path
222
+ expandedInclude.push(inputPath);
223
+ expandedInclude.push('**/' + inputPath);
224
+ } else if (stat.isDirectory()) {
225
+ // For directories, add recursive patterns
226
+ expandedInclude.push(inputPath + '/**');
227
+ expandedInclude.push('**/' + inputPath + '/**');
228
+ }
229
+ } else {
230
+ // If path doesn't exist, assume it's a pattern and add both file and directory variants
231
+ expandedInclude.push(inputPath);
232
+ expandedInclude.push(inputPath + '/**');
233
+ expandedInclude.push('**/' + inputPath);
234
+ expandedInclude.push('**/' + inputPath + '/**');
235
+ }
236
+ } catch (error) {
237
+ // Fallback to original logic if file system check fails
238
+ expandedInclude.push(inputPath + '/**');
239
+ expandedInclude.push('**/' + inputPath + '/**');
240
+ }
241
+ }
242
+ result.include = expandedInclude;
243
+
244
+ console.log(chalk.gray(`📁 AUTO-EXPANSION: Auto-expanded include patterns: ${expandedInclude.join(', ')}`));
245
+ } else {
246
+ console.log(chalk.gray(`✅ AUTO-EXPANSION: No expansion needed`));
247
+ }
248
+
249
+ return result;
250
+ }
251
+
164
252
  /**
165
253
  * Rule C006: processIgnorePatterns - verb-noun naming
166
254
  * Convert deprecated ignorePatterns to exclude for backward compatibility
@@ -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
+ };