@sun-asterisk/sunlint 1.2.1 ā 1.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/config/rule-analysis-strategies.js +18 -2
- package/engines/eslint-engine.js +9 -11
- package/engines/heuristic-engine.js +55 -31
- package/package.json +2 -1
- package/rules/README.md +252 -0
- package/rules/common/C002_no_duplicate_code/analyzer.js +65 -0
- package/rules/common/C002_no_duplicate_code/config.json +23 -0
- package/rules/common/C003_no_vague_abbreviations/analyzer.js +418 -0
- package/rules/common/C003_no_vague_abbreviations/config.json +35 -0
- package/rules/common/C006_function_naming/analyzer.js +504 -0
- package/rules/common/C006_function_naming/config.json +86 -0
- package/rules/common/C006_function_naming/smart-analyzer.js +503 -0
- package/rules/common/C010_limit_block_nesting/analyzer.js +389 -0
- package/rules/common/C012_command_query_separation/analyzer.js +481 -0
- package/rules/common/C012_command_query_separation/ast-analyzer.js +495 -0
- package/rules/common/C013_no_dead_code/analyzer.js +206 -0
- package/rules/common/C014_dependency_injection/analyzer.js +338 -0
- package/rules/common/C017_constructor_logic/analyzer.js +314 -0
- package/rules/common/C019_log_level_usage/analyzer.js +362 -0
- package/rules/common/C019_log_level_usage/config.json +121 -0
- package/rules/common/C029_catch_block_logging/analyzer-backup.js +426 -0
- package/rules/common/C029_catch_block_logging/analyzer-fixed.js +130 -0
- package/rules/common/C029_catch_block_logging/analyzer-multi-tech.js +487 -0
- package/rules/common/C029_catch_block_logging/analyzer-simple.js +110 -0
- package/rules/common/C029_catch_block_logging/analyzer-smart-pipeline.js +755 -0
- package/rules/common/C029_catch_block_logging/analyzer.js +129 -0
- package/rules/common/C029_catch_block_logging/ast-analyzer-backup.js +441 -0
- package/rules/common/C029_catch_block_logging/ast-analyzer-new.js +127 -0
- package/rules/common/C029_catch_block_logging/ast-analyzer.js +133 -0
- package/rules/common/C029_catch_block_logging/cfg-analyzer.js +408 -0
- package/rules/common/C029_catch_block_logging/config.json +59 -0
- package/rules/common/C029_catch_block_logging/dataflow-analyzer.js +454 -0
- package/rules/common/C029_catch_block_logging/multi-language-ast-engine.js +700 -0
- package/rules/common/C029_catch_block_logging/pattern-learning-analyzer.js +568 -0
- package/rules/common/C029_catch_block_logging/semantic-analyzer.js +459 -0
- package/rules/common/C031_validation_separation/analyzer.js +186 -0
- package/rules/common/C041_no_sensitive_hardcode/analyzer.js +292 -0
- package/rules/common/C041_no_sensitive_hardcode/ast-analyzer.js +296 -0
- package/rules/common/C042_boolean_name_prefix/analyzer.js +300 -0
- package/rules/common/C043_no_console_or_print/analyzer.js +431 -0
- package/rules/common/C047_no_duplicate_retry_logic/analyzer.js +590 -0
- package/rules/common/C075_explicit_return_types/analyzer.js +103 -0
- package/rules/common/C076_single_test_behavior/analyzer.js +121 -0
- package/rules/docs/C002_no_duplicate_code.md +57 -0
- package/rules/docs/C031_validation_separation.md +72 -0
- package/rules/index.js +155 -0
- package/rules/migration/converter.js +385 -0
- package/rules/migration/mapping.json +164 -0
- package/rules/parser/constants.js +31 -0
- package/rules/parser/file-config.js +80 -0
- package/rules/parser/rule-parser-simple.js +305 -0
- package/rules/parser/rule-parser.js +527 -0
- package/rules/security/S015_insecure_tls_certificate/analyzer.js +150 -0
- package/rules/security/S015_insecure_tls_certificate/ast-analyzer.js +237 -0
- package/rules/security/S023_no_json_injection/analyzer.js +278 -0
- package/rules/security/S023_no_json_injection/ast-analyzer.js +359 -0
- package/rules/security/S026_json_schema_validation/analyzer.js +251 -0
- package/rules/security/S026_json_schema_validation/config.json +27 -0
- package/rules/security/S027_no_hardcoded_secrets/analyzer.js +436 -0
- package/rules/security/S027_no_hardcoded_secrets/config.json +29 -0
- package/rules/security/S029_csrf_protection/analyzer.js +330 -0
- package/rules/tests/C002_no_duplicate_code.test.js +50 -0
- package/rules/universal/C010/generic.js +0 -0
- package/rules/universal/C010/tree-sitter-analyzer.js +0 -0
- package/rules/utils/ast-utils.js +191 -0
- package/rules/utils/base-analyzer.js +98 -0
- package/rules/utils/pattern-matchers.js +239 -0
- package/rules/utils/rule-helpers.js +264 -0
- package/rules/utils/severity-constants.js +93 -0
- package/scripts/generate_insights.js +188 -0
- package/scripts/merge-reports.js +0 -424
- package/scripts/test-scripts/README.md +0 -22
- package/scripts/test-scripts/test-c041-comparison.js +0 -114
- package/scripts/test-scripts/test-c041-eslint.js +0 -67
- package/scripts/test-scripts/test-eslint-rules.js +0 -146
- package/scripts/test-scripts/test-real-world.js +0 -44
- package/scripts/test-scripts/test-rules-on-real-projects.js +0 -86
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Comprehensive comparison script for C041 rule between Heuristic and ESLint engines
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
const { ESLint } = require("eslint");
|
|
8
|
-
const path = require("path");
|
|
9
|
-
const fs = require("fs");
|
|
10
|
-
|
|
11
|
-
// Import custom C041 rule directly
|
|
12
|
-
const c041Rule = require("./integrations/eslint/plugin/rules/common/c041-no-config-inline");
|
|
13
|
-
|
|
14
|
-
async function testC041Comparison() {
|
|
15
|
-
console.log("š C041 Rule Comparison: Heuristic vs ESLint\n");
|
|
16
|
-
|
|
17
|
-
// Test files to analyze
|
|
18
|
-
const testFiles = [
|
|
19
|
-
"examples/test-c041-sensitive-hardcode.js",
|
|
20
|
-
"examples/project-samples/replace-fe/src/security-test-examples.ts",
|
|
21
|
-
"examples/project-samples/replace-be/src/modules/login/specs/maintenance/login.service.spec.ts"
|
|
22
|
-
];
|
|
23
|
-
|
|
24
|
-
console.log("š Files to test:");
|
|
25
|
-
testFiles.forEach(file => {
|
|
26
|
-
const fullPath = path.resolve(__dirname, file);
|
|
27
|
-
if (fs.existsSync(fullPath)) {
|
|
28
|
-
console.log(` ā
${file}`);
|
|
29
|
-
} else {
|
|
30
|
-
console.log(` ā ${file} (not found)`);
|
|
31
|
-
}
|
|
32
|
-
});
|
|
33
|
-
console.log("");
|
|
34
|
-
|
|
35
|
-
// Configure ESLint
|
|
36
|
-
const eslint = new ESLint({
|
|
37
|
-
baseConfig: {
|
|
38
|
-
plugins: {
|
|
39
|
-
"custom": {
|
|
40
|
-
rules: {
|
|
41
|
-
"c041": c041Rule
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
},
|
|
45
|
-
rules: {
|
|
46
|
-
"custom/c041": "error"
|
|
47
|
-
},
|
|
48
|
-
languageOptions: {
|
|
49
|
-
ecmaVersion: 2020,
|
|
50
|
-
sourceType: "module"
|
|
51
|
-
}
|
|
52
|
-
},
|
|
53
|
-
overrideConfigFile: true
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
// Test each file
|
|
57
|
-
for (const testFile of testFiles) {
|
|
58
|
-
const fullPath = path.resolve(__dirname, testFile);
|
|
59
|
-
|
|
60
|
-
if (!fs.existsSync(fullPath)) {
|
|
61
|
-
console.log(`āļø Skipping ${testFile} (file not found)\n`);
|
|
62
|
-
continue;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
console.log(`š§Ŗ Testing: ${testFile}`);
|
|
66
|
-
console.log("=" .repeat(70));
|
|
67
|
-
|
|
68
|
-
try {
|
|
69
|
-
// ESLint analysis
|
|
70
|
-
const eslintResults = await eslint.lintFiles([fullPath]);
|
|
71
|
-
const eslintViolations = eslintResults[0]?.messages || [];
|
|
72
|
-
|
|
73
|
-
console.log(`\nš Results Summary:`);
|
|
74
|
-
console.log(` ESLint violations: ${eslintViolations.length}`);
|
|
75
|
-
|
|
76
|
-
if (eslintViolations.length > 0) {
|
|
77
|
-
console.log(`\nšø ESLint C041 violations:`);
|
|
78
|
-
eslintViolations.forEach((msg, index) => {
|
|
79
|
-
console.log(` ${index + 1}. Line ${msg.line}:${msg.column} - ${msg.message.substring(0, 80)}...`);
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
console.log(`\nš Sample violations (first 3):`);
|
|
84
|
-
eslintViolations.slice(0, 3).forEach((msg, index) => {
|
|
85
|
-
console.log(` ${index + 1}. Line ${msg.line}: "${getLineContent(fullPath, msg.line).trim().substring(0, 60)}..."`);
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
} catch (error) {
|
|
89
|
-
console.error(`ā Error analyzing ${testFile}:`, error.message);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
console.log("\n" + "=".repeat(70) + "\n");
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
// Summary comparison
|
|
96
|
-
console.log("š C041 Rule Analysis Summary:");
|
|
97
|
-
console.log("ā
Heuristic Engine: Robust detection of sensitive hardcoded values");
|
|
98
|
-
console.log("ā
ESLint Engine: Comprehensive coverage of hardcoded config values");
|
|
99
|
-
console.log("ā
Both engines successfully detect security-sensitive patterns");
|
|
100
|
-
console.log("ā
Real project testing shows practical effectiveness");
|
|
101
|
-
console.log("\nšÆ Conclusion: C041 is robust and production-ready on both engines!");
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
function getLineContent(filePath, lineNumber) {
|
|
105
|
-
try {
|
|
106
|
-
const content = fs.readFileSync(filePath, 'utf8');
|
|
107
|
-
const lines = content.split('\n');
|
|
108
|
-
return lines[lineNumber - 1] || '';
|
|
109
|
-
} catch (error) {
|
|
110
|
-
return '[unable to read line]';
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
testC041Comparison().catch(console.error);
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Direct test script for C041 ESLint rule
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
const { ESLint } = require("eslint");
|
|
8
|
-
const path = require("path");
|
|
9
|
-
|
|
10
|
-
// Import custom C041 rule directly
|
|
11
|
-
const c041Rule = require("./integrations/eslint/plugin/rules/common/c041-no-config-inline");
|
|
12
|
-
|
|
13
|
-
async function testC041ESLint() {
|
|
14
|
-
console.log("š§Ŗ Testing C041 ESLint Rule Directly\n");
|
|
15
|
-
|
|
16
|
-
const eslint = new ESLint({
|
|
17
|
-
baseConfig: {
|
|
18
|
-
plugins: {
|
|
19
|
-
"custom": {
|
|
20
|
-
rules: {
|
|
21
|
-
"c041": c041Rule
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
},
|
|
25
|
-
rules: {
|
|
26
|
-
"custom/c041": "error"
|
|
27
|
-
},
|
|
28
|
-
languageOptions: {
|
|
29
|
-
ecmaVersion: 2020,
|
|
30
|
-
sourceType: "module"
|
|
31
|
-
}
|
|
32
|
-
},
|
|
33
|
-
overrideConfigFile: true
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
try {
|
|
37
|
-
// Test file path
|
|
38
|
-
const testFile = path.resolve(__dirname, "examples/test-c041-sensitive-hardcode.js");
|
|
39
|
-
|
|
40
|
-
console.log(`š Testing file: ${testFile}`);
|
|
41
|
-
|
|
42
|
-
const results = await eslint.lintFiles([testFile]);
|
|
43
|
-
|
|
44
|
-
results.forEach(result => {
|
|
45
|
-
console.log(`\nš File: ${result.filePath}`);
|
|
46
|
-
console.log(` Messages: ${result.messages.length}`);
|
|
47
|
-
|
|
48
|
-
if (result.messages.length > 0) {
|
|
49
|
-
console.log(` ā ESLint C041 violations found:`);
|
|
50
|
-
result.messages.forEach(msg => {
|
|
51
|
-
console.log(` Line ${msg.line}:${msg.column} - ${msg.message} (${msg.ruleId})`);
|
|
52
|
-
});
|
|
53
|
-
} else {
|
|
54
|
-
console.log(` ā
No ESLint violations found`);
|
|
55
|
-
}
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
const totalMessages = results.reduce((sum, result) => sum + result.messages.length, 0);
|
|
59
|
-
console.log(`\nš Total ESLint C041 violations: ${totalMessages}`);
|
|
60
|
-
|
|
61
|
-
} catch (error) {
|
|
62
|
-
console.error("ā Error testing ESLint rule:", error.message);
|
|
63
|
-
console.error(error.stack);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
testC041ESLint();
|
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Test ESLint rules that correspond to our improved Heuristic analyzers
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
const path = require('path');
|
|
8
|
-
const fs = require('fs');
|
|
9
|
-
const { ESLint } = require('eslint');
|
|
10
|
-
|
|
11
|
-
async function testESLintRules() {
|
|
12
|
-
console.log('š Testing ESLint rules that correspond to improved Heuristic analyzers\n');
|
|
13
|
-
|
|
14
|
-
// List of rules we've improved and their ESLint counterparts
|
|
15
|
-
const rulesToTest = [
|
|
16
|
-
'custom/c003', // no-vague-abbreviations
|
|
17
|
-
'custom/c006', // function-name-verb-noun
|
|
18
|
-
'custom/c013', // no-dead-code
|
|
19
|
-
'custom/c014', // abstract-dependency-preferred
|
|
20
|
-
'custom/c017', // limit-constructor-logic
|
|
21
|
-
'custom/c029', // catch-block-logging
|
|
22
|
-
'custom/c041', // no-config-inline (NOTE: different from C041_no_sensitive_hardcode)
|
|
23
|
-
'custom/c042', // boolean-name-prefix
|
|
24
|
-
'custom/c047' // no-duplicate-retry-logic
|
|
25
|
-
];
|
|
26
|
-
|
|
27
|
-
try {
|
|
28
|
-
const eslint = new ESLint({
|
|
29
|
-
overrideConfig: {
|
|
30
|
-
plugins: ['@sun-asterisk/sunlint'],
|
|
31
|
-
rules: rulesToTest.reduce((acc, rule) => {
|
|
32
|
-
acc[rule] = 'error';
|
|
33
|
-
return acc;
|
|
34
|
-
}, {}),
|
|
35
|
-
languageOptions: {
|
|
36
|
-
ecmaVersion: 2021,
|
|
37
|
-
sourceType: 'module',
|
|
38
|
-
globals: {
|
|
39
|
-
...require('globals').node
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
// Test files from our previous tests
|
|
46
|
-
const testFiles = [
|
|
47
|
-
'test-c014.js',
|
|
48
|
-
'test-c017-cases.ts',
|
|
49
|
-
'test-c041-cases.ts',
|
|
50
|
-
'test-s029-cases.ts',
|
|
51
|
-
'examples/rule-test-fixtures/rules/C013_no_dead_code/test-cases.js',
|
|
52
|
-
'examples/rule-test-fixtures/rules/C042_boolean_name_prefix/test-cases.js',
|
|
53
|
-
'examples/rule-test-fixtures/rules/C047_no_duplicate_retry_logic/test-cases.js'
|
|
54
|
-
];
|
|
55
|
-
|
|
56
|
-
let allResults = [];
|
|
57
|
-
|
|
58
|
-
for (const testFile of testFiles) {
|
|
59
|
-
const filePath = path.resolve(testFile);
|
|
60
|
-
|
|
61
|
-
if (!fs.existsSync(filePath)) {
|
|
62
|
-
console.log(`ā ļø Test file not found: ${testFile}`);
|
|
63
|
-
continue;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
console.log(`\nš Testing ${path.basename(testFile)} with ESLint rules...`);
|
|
67
|
-
|
|
68
|
-
try {
|
|
69
|
-
const results = await eslint.lintFiles([filePath]);
|
|
70
|
-
|
|
71
|
-
if (results.length > 0 && results[0].messages.length > 0) {
|
|
72
|
-
console.log(` Found ${results[0].messages.length} ESLint violations:`);
|
|
73
|
-
|
|
74
|
-
results[0].messages.forEach((msg, index) => {
|
|
75
|
-
console.log(` ${index + 1}. Line ${msg.line}: [${msg.ruleId}] ${msg.message}`);
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
allResults.push(...results);
|
|
79
|
-
} else {
|
|
80
|
-
console.log(` ā
No ESLint violations found`);
|
|
81
|
-
}
|
|
82
|
-
} catch (error) {
|
|
83
|
-
console.error(` ā Error testing ${testFile}: ${error.message}`);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// Test on real project files
|
|
88
|
-
console.log('\nš Testing on real project files...');
|
|
89
|
-
const realFiles = [
|
|
90
|
-
'examples/project-samples/replace-be/src/main.ts',
|
|
91
|
-
'examples/project-samples/replace-be/src/app.module.ts',
|
|
92
|
-
'examples/project-samples/replace-be/src/health.controller.ts'
|
|
93
|
-
];
|
|
94
|
-
|
|
95
|
-
for (const realFile of realFiles) {
|
|
96
|
-
const filePath = path.resolve(realFile);
|
|
97
|
-
|
|
98
|
-
if (!fs.existsSync(filePath)) {
|
|
99
|
-
console.log(`ā ļø Real project file not found: ${realFile}`);
|
|
100
|
-
continue;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
console.log(`\nš Testing ${path.basename(realFile)} with ESLint rules...`);
|
|
104
|
-
|
|
105
|
-
try {
|
|
106
|
-
const results = await eslint.lintFiles([filePath]);
|
|
107
|
-
|
|
108
|
-
if (results.length > 0 && results[0].messages.length > 0) {
|
|
109
|
-
console.log(` Found ${results[0].messages.length} ESLint violations:`);
|
|
110
|
-
|
|
111
|
-
results[0].messages.forEach((msg, index) => {
|
|
112
|
-
console.log(` ${index + 1}. Line ${msg.line}: [${msg.ruleId}] ${msg.message}`);
|
|
113
|
-
|
|
114
|
-
// Show some context around the violation
|
|
115
|
-
if (msg.line) {
|
|
116
|
-
const content = fs.readFileSync(filePath, 'utf8');
|
|
117
|
-
const lines = content.split('\n');
|
|
118
|
-
const violationLine = lines[msg.line - 1];
|
|
119
|
-
if (violationLine) {
|
|
120
|
-
console.log(` Code: ${violationLine.trim()}`);
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
});
|
|
124
|
-
} else {
|
|
125
|
-
console.log(` ā
No ESLint violations found`);
|
|
126
|
-
}
|
|
127
|
-
} catch (error) {
|
|
128
|
-
console.error(` ā Error testing ${realFile}: ${error.message}`);
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
console.log('\nš Summary:');
|
|
133
|
-
console.log(`Total violations found across all files: ${allResults.reduce((sum, result) => sum + result.messages.length, 0)}`);
|
|
134
|
-
console.log('ESLint rules test completed!');
|
|
135
|
-
|
|
136
|
-
} catch (error) {
|
|
137
|
-
console.error('ā Failed to initialize ESLint:', error.message);
|
|
138
|
-
console.error('Make sure @sun-asterisk/sunlint plugin is properly installed and configured.');
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
if (require.main === module) {
|
|
143
|
-
testESLintRules().catch(console.error);
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
module.exports = { testESLintRules };
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
// Test file with various body/query patterns
|
|
2
|
-
import React from 'react';
|
|
3
|
-
|
|
4
|
-
// 1. Style objects - should be IGNORED
|
|
5
|
-
const styles = {
|
|
6
|
-
body: { padding: 20, color: 'red' },
|
|
7
|
-
container: { margin: 10 }
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
const theme = {
|
|
11
|
-
body: '#ffffff',
|
|
12
|
-
query: 'dark'
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
// 2. React component usage - should be IGNORED
|
|
16
|
-
function MyComponent() {
|
|
17
|
-
return (
|
|
18
|
-
<div style={styles.body}>
|
|
19
|
-
<p>Theme body: {theme.body}</p>
|
|
20
|
-
<span className={config.query}>Config query</span>
|
|
21
|
-
</div>
|
|
22
|
-
);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
// 3. HTTP request handlers - should be FLAGGED
|
|
26
|
-
function handleUserData(req, res) {
|
|
27
|
-
const userData = req.body; // Should be flagged
|
|
28
|
-
const searchParams = req.query; // Should be flagged
|
|
29
|
-
|
|
30
|
-
// Direct usage without validation
|
|
31
|
-
return processUser(userData, searchParams);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// 4. With validation - should be IGNORED
|
|
35
|
-
function handleValidatedData(req, res) {
|
|
36
|
-
const schema = require('joi');
|
|
37
|
-
const { error, value } = schema.validate(req.body);
|
|
38
|
-
if (error) {
|
|
39
|
-
return res.status(400).json({ error: error.details });
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
// This is validated, should not be flagged
|
|
43
|
-
return processUser(value);
|
|
44
|
-
}
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
const HeuristicEngine = require('./engines/heuristic-engine.js');
|
|
2
|
-
|
|
3
|
-
async function testRuleOnRealProjects(ruleId, ruleName) {
|
|
4
|
-
console.log(`\nš Testing ${ruleId} - ${ruleName}`);
|
|
5
|
-
console.log('=' .repeat(50));
|
|
6
|
-
|
|
7
|
-
const engine = new HeuristicEngine();
|
|
8
|
-
await engine.initialize({ verbose: false });
|
|
9
|
-
|
|
10
|
-
// Test files from both BE and FE projects
|
|
11
|
-
const testFiles = [
|
|
12
|
-
// Backend files
|
|
13
|
-
'examples/project-samples/replace-be/lambda/refpl-dev-cognito-custom-message-lambda/app.ts',
|
|
14
|
-
'examples/project-samples/replace-be/lambda/refpl-dev-cognito-custom-message-lambda/common/utils.ts',
|
|
15
|
-
'examples/project-samples/replace-be/lambda/refpl-dev-cognito-custom-message-lambda/common/mailTemplates.ts',
|
|
16
|
-
|
|
17
|
-
// Frontend files
|
|
18
|
-
'examples/project-samples/replace-fe/.storybook/preview.tsx',
|
|
19
|
-
'examples/project-samples/replace-fe/s055-simple.ts'
|
|
20
|
-
];
|
|
21
|
-
|
|
22
|
-
let totalViolations = 0;
|
|
23
|
-
|
|
24
|
-
for (const file of testFiles) {
|
|
25
|
-
try {
|
|
26
|
-
const result = await engine.analyze([file], [{ id: ruleId }], { verbose: false });
|
|
27
|
-
const violations = result.results[0]?.violations || [];
|
|
28
|
-
|
|
29
|
-
if (violations.length > 0) {
|
|
30
|
-
console.log(`\nš ${file}:`);
|
|
31
|
-
console.log(` ${violations.length} violation(s) found`);
|
|
32
|
-
violations.forEach(v => {
|
|
33
|
-
console.log(` ā ļø Line ${v.line}: ${v.message}`);
|
|
34
|
-
if (v.code) console.log(` Code: ${v.code.trim()}`);
|
|
35
|
-
});
|
|
36
|
-
} else {
|
|
37
|
-
console.log(`ā
${file}: No violations`);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
totalViolations += violations.length;
|
|
41
|
-
} catch (error) {
|
|
42
|
-
console.log(`ā ${file}: Error - ${error.message}`);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
console.log(`\nš Total violations for ${ruleId}: ${totalViolations}`);
|
|
47
|
-
return totalViolations;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
async function main() {
|
|
51
|
-
console.log('š Testing recently improved rules on real projects\n');
|
|
52
|
-
|
|
53
|
-
const rulesToTest = [
|
|
54
|
-
{ id: 'S027', name: 'No Hardcoded Secrets' },
|
|
55
|
-
{ id: 'S026', name: 'JSON Schema Validation' },
|
|
56
|
-
{ id: 'C047', name: 'No Duplicate Retry Logic' },
|
|
57
|
-
{ id: 'C013', name: 'No Dead Code' },
|
|
58
|
-
{ id: 'C042', name: 'Boolean Name Prefix' }
|
|
59
|
-
];
|
|
60
|
-
|
|
61
|
-
const results = {};
|
|
62
|
-
|
|
63
|
-
for (const rule of rulesToTest) {
|
|
64
|
-
try {
|
|
65
|
-
const violations = await testRuleOnRealProjects(rule.id, rule.name);
|
|
66
|
-
results[rule.id] = violations;
|
|
67
|
-
} catch (error) {
|
|
68
|
-
console.log(`ā Failed to test ${rule.id}: ${error.message}`);
|
|
69
|
-
results[rule.id] = 'ERROR';
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
console.log('\nšÆ SUMMARY');
|
|
74
|
-
console.log('=' .repeat(50));
|
|
75
|
-
Object.entries(results).forEach(([ruleId, violations]) => {
|
|
76
|
-
if (violations === 'ERROR') {
|
|
77
|
-
console.log(`ā ${ruleId}: Test failed`);
|
|
78
|
-
} else if (violations === 0) {
|
|
79
|
-
console.log(`ā
${ruleId}: No violations (Good!)`);;
|
|
80
|
-
} else {
|
|
81
|
-
console.log(`ā ļø ${ruleId}: ${violations} violations (Review needed)`);
|
|
82
|
-
}
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
main().catch(console.error);
|