@sun-asterisk/sunlint 1.3.4 ā 1.3.5
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/CHANGELOG.md +32 -0
- package/config/presets/all.json +49 -48
- package/config/presets/beginner.json +7 -18
- package/config/presets/ci.json +63 -27
- package/config/presets/maintainability.json +6 -4
- package/config/presets/performance.json +4 -3
- package/config/presets/quality.json +11 -50
- package/config/presets/recommended.json +83 -10
- package/config/presets/security.json +20 -19
- package/config/presets/strict.json +6 -13
- package/config/rules/enhanced-rules-registry.json +64 -7
- package/core/config-preset-resolver.js +7 -2
- package/package.json +1 -1
- package/rules/common/C067_no_hardcoded_config/analyzer.js +95 -0
- package/rules/common/C067_no_hardcoded_config/config.json +81 -0
- package/rules/common/C067_no_hardcoded_config/symbol-based-analyzer.js +1000 -0
- package/rules/security/S024_xpath_xxe_protection/analyzer.js +242 -0
- package/rules/security/S024_xpath_xxe_protection/config.json +152 -0
- package/rules/security/S024_xpath_xxe_protection/regex-based-analyzer.js +338 -0
- package/rules/security/S024_xpath_xxe_protection/symbol-based-analyzer.js +474 -0
- package/rules/security/S025_server_side_validation/README.md +179 -0
- package/rules/security/S025_server_side_validation/analyzer.js +242 -0
- package/rules/security/S025_server_side_validation/config.json +111 -0
- package/rules/security/S025_server_side_validation/regex-based-analyzer.js +388 -0
- package/rules/security/S025_server_side_validation/symbol-based-analyzer.js +523 -0
- package/scripts/README.md +83 -0
- package/scripts/analyze-core-rules.js +151 -0
- package/scripts/generate-presets.js +202 -0
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
const { SimpleRuleParser } = require('../rules/parser/rule-parser-simple');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
|
|
5
|
+
console.log('=== ANALYZING COMMON AND SECURITY RULES ===\n');
|
|
6
|
+
|
|
7
|
+
const parser = new SimpleRuleParser();
|
|
8
|
+
|
|
9
|
+
// Parse common rules
|
|
10
|
+
const commonRules = parser.parseRuleFile('../origin-rules/common-en.md');
|
|
11
|
+
const securityRules = parser.parseRuleFile('../origin-rules/security-en.md');
|
|
12
|
+
|
|
13
|
+
console.log(`š COMMON RULES: ${commonRules.length} total rules`);
|
|
14
|
+
console.log(`š SECURITY RULES: ${securityRules.length} total rules\n`);
|
|
15
|
+
|
|
16
|
+
// Filter activated rules only
|
|
17
|
+
const activatedCommon = commonRules.filter(rule => rule.status === 'activated');
|
|
18
|
+
const activatedSecurity = securityRules.filter(rule => rule.status === 'activated');
|
|
19
|
+
|
|
20
|
+
console.log(`ā
ACTIVATED COMMON RULES: ${activatedCommon.length}`);
|
|
21
|
+
activatedCommon.forEach(rule => {
|
|
22
|
+
const principles = Array.isArray(rule.principles) ? rule.principles.join(', ') : rule.principles || 'N/A';
|
|
23
|
+
console.log(` ${rule.id}: ${rule.title} [${principles}]`);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
console.log(`\nš ACTIVATED SECURITY RULES: ${activatedSecurity.length}`);
|
|
27
|
+
activatedSecurity.forEach(rule => {
|
|
28
|
+
const principles = Array.isArray(rule.principles) ? rule.principles.join(', ') : rule.principles || 'N/A';
|
|
29
|
+
console.log(` ${rule.id}: ${rule.title} [${principles}]`);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
// Analyze principles distribution
|
|
33
|
+
console.log('\n=== PRINCIPLE DISTRIBUTION ===');
|
|
34
|
+
const principleCount = {};
|
|
35
|
+
[...activatedCommon, ...activatedSecurity].forEach(rule => {
|
|
36
|
+
if (Array.isArray(rule.principles)) {
|
|
37
|
+
rule.principles.forEach(principle => {
|
|
38
|
+
principleCount[principle] = (principleCount[principle] || 0) + 1;
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
Object.entries(principleCount).sort((a,b) => b[1] - a[1]).forEach(([principle, count]) => {
|
|
44
|
+
console.log(`${principle}: ${count} rules`);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
// Generate preset configurations
|
|
48
|
+
console.log('\n=== GENERATING PRESET CONFIGS ===');
|
|
49
|
+
|
|
50
|
+
// Recommended preset (balanced)
|
|
51
|
+
const recommendedRules = {};
|
|
52
|
+
[...activatedCommon, ...activatedSecurity].forEach(rule => {
|
|
53
|
+
if (rule.id) {
|
|
54
|
+
// Use warn for most rules, error for critical security
|
|
55
|
+
if (rule.id.startsWith('S') && rule.severity === 'critical') {
|
|
56
|
+
recommendedRules[rule.id] = 'error';
|
|
57
|
+
} else {
|
|
58
|
+
recommendedRules[rule.id] = 'warn';
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
// Security preset (security rules only)
|
|
64
|
+
const securityPresetRules = {};
|
|
65
|
+
activatedSecurity.forEach(rule => {
|
|
66
|
+
if (rule.id) {
|
|
67
|
+
securityPresetRules[rule.id] = rule.severity === 'critical' ? 'error' : 'warn';
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
// Quality preset (non-security common rules)
|
|
72
|
+
const qualityPresetRules = {};
|
|
73
|
+
activatedCommon.forEach(rule => {
|
|
74
|
+
if (rule.id && (!rule.principles || !rule.principles.includes('SECURITY'))) {
|
|
75
|
+
qualityPresetRules[rule.id] = 'warn';
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
console.log(`š RECOMMENDED preset: ${Object.keys(recommendedRules).length} rules`);
|
|
80
|
+
console.log(`š SECURITY preset: ${Object.keys(securityPresetRules).length} rules`);
|
|
81
|
+
console.log(`ā QUALITY preset: ${Object.keys(qualityPresetRules).length} rules`);
|
|
82
|
+
|
|
83
|
+
// Generate preset files
|
|
84
|
+
const presetConfigs = {
|
|
85
|
+
recommended: {
|
|
86
|
+
name: "@sun/sunlint/recommended",
|
|
87
|
+
description: "Sun* Engineering recommended configuration - essential rules from core files (common-en.md + security-en.md)",
|
|
88
|
+
rules: recommendedRules,
|
|
89
|
+
categories: {
|
|
90
|
+
quality: "warn",
|
|
91
|
+
security: "error"
|
|
92
|
+
},
|
|
93
|
+
languages: ["typescript", "javascript", "dart", "java", "kotlin", "swift"],
|
|
94
|
+
exclude: ["**/node_modules/**", "**/build/**", "**/dist/**", "**/*.generated.*", "**/*.min.*"],
|
|
95
|
+
metadata: {
|
|
96
|
+
totalRules: Object.keys(recommendedRules).length,
|
|
97
|
+
coreRules: Object.keys(recommendedRules).length,
|
|
98
|
+
approach: "core-files-only",
|
|
99
|
+
source: "common-en.md + security-en.md",
|
|
100
|
+
lastUpdated: new Date().toISOString(),
|
|
101
|
+
version: "2.0.0"
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
security: {
|
|
105
|
+
name: "@sun/sunlint/security",
|
|
106
|
+
description: "Security-focused configuration with all security rules",
|
|
107
|
+
rules: securityPresetRules,
|
|
108
|
+
categories: {
|
|
109
|
+
security: "error"
|
|
110
|
+
},
|
|
111
|
+
languages: ["typescript", "javascript", "dart", "java", "kotlin", "swift"],
|
|
112
|
+
exclude: ["**/node_modules/**", "**/build/**", "**/dist/**", "**/*.generated.*", "**/*.min.*"],
|
|
113
|
+
metadata: {
|
|
114
|
+
totalRules: Object.keys(securityPresetRules).length,
|
|
115
|
+
securityRules: Object.keys(securityPresetRules).length,
|
|
116
|
+
approach: "security-focused",
|
|
117
|
+
source: "security-en.md",
|
|
118
|
+
lastUpdated: new Date().toISOString(),
|
|
119
|
+
version: "2.0.0"
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
quality: {
|
|
123
|
+
name: "@sun/sunlint/quality",
|
|
124
|
+
description: "Code quality and best practices focused configuration",
|
|
125
|
+
rules: qualityPresetRules,
|
|
126
|
+
categories: {
|
|
127
|
+
quality: "warn",
|
|
128
|
+
maintainability: "warn",
|
|
129
|
+
testability: "warn"
|
|
130
|
+
},
|
|
131
|
+
languages: ["typescript", "javascript", "dart", "java", "kotlin", "swift"],
|
|
132
|
+
exclude: ["**/node_modules/**", "**/build/**", "**/dist/**", "**/*.generated.*", "**/*.min.*"],
|
|
133
|
+
metadata: {
|
|
134
|
+
totalRules: Object.keys(qualityPresetRules).length,
|
|
135
|
+
qualityRules: Object.keys(qualityPresetRules).length,
|
|
136
|
+
approach: "quality-focused",
|
|
137
|
+
source: "common-en.md (non-security rules)",
|
|
138
|
+
lastUpdated: new Date().toISOString(),
|
|
139
|
+
version: "2.0.0"
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
// Write preset files
|
|
145
|
+
Object.entries(presetConfigs).forEach(([name, config]) => {
|
|
146
|
+
const filePath = `./config/presets/${name}.json`;
|
|
147
|
+
fs.writeFileSync(filePath, JSON.stringify(config, null, 2));
|
|
148
|
+
console.log(`ā
Generated ${filePath}`);
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
console.log('\n=== PRESET GENERATION COMPLETE ===');
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
const { SimpleRuleParser } = require('../rules/parser/rule-parser-simple');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
|
|
4
|
+
console.log('=== GENERATING ADDITIONAL PRESETS ===\n');
|
|
5
|
+
|
|
6
|
+
const parser = new SimpleRuleParser();
|
|
7
|
+
const commonRules = parser.parseRuleFile('../origin-rules/common-en.md');
|
|
8
|
+
const securityRules = parser.parseRuleFile('../origin-rules/security-en.md');
|
|
9
|
+
const allRules = [...commonRules, ...securityRules];
|
|
10
|
+
const activatedRules = allRules.filter(rule => rule.status === 'activated');
|
|
11
|
+
|
|
12
|
+
// Generate additional presets
|
|
13
|
+
|
|
14
|
+
// 1. Beginner preset (basic rules only)
|
|
15
|
+
const beginnerRules = {};
|
|
16
|
+
const beginnerRuleIds = ['C019', 'C029', 'C006']; // Basic logging, error handling, naming
|
|
17
|
+
activatedRules.forEach(rule => {
|
|
18
|
+
if (beginnerRuleIds.includes(rule.id)) {
|
|
19
|
+
beginnerRules[rule.id] = rule.id === 'C006' ? 'info' : 'warn';
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
// 2. CI preset (critical rules only)
|
|
24
|
+
const ciRules = {};
|
|
25
|
+
activatedRules.forEach(rule => {
|
|
26
|
+
if (rule.id === 'C019' || rule.id === 'C029' || rule.id.startsWith('S')) {
|
|
27
|
+
ciRules[rule.id] = rule.severity === 'critical' ? 'error' : 'error';
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
// Turn off naming for CI
|
|
31
|
+
ciRules['C006'] = 'off';
|
|
32
|
+
|
|
33
|
+
// 3. Strict preset (all rules as errors)
|
|
34
|
+
const strictRules = {};
|
|
35
|
+
const strictRuleIds = ['C019', 'C029', 'C006'];
|
|
36
|
+
activatedRules.forEach(rule => {
|
|
37
|
+
if (strictRuleIds.includes(rule.id)) {
|
|
38
|
+
strictRules[rule.id] = 'error';
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
// 4. Maintainability preset
|
|
43
|
+
const maintainabilityRules = {};
|
|
44
|
+
activatedRules.forEach(rule => {
|
|
45
|
+
if (rule.principles && rule.principles.includes('MAINTAINABILITY')) {
|
|
46
|
+
maintainabilityRules[rule.id] = 'warn';
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
// 5. Performance preset
|
|
51
|
+
const performanceRules = {};
|
|
52
|
+
activatedRules.forEach(rule => {
|
|
53
|
+
if (rule.principles && rule.principles.includes('PERFORMANCE')) {
|
|
54
|
+
performanceRules[rule.id] = 'warn';
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
// 6. All preset (all activated rules)
|
|
59
|
+
const allActivatedRules = {};
|
|
60
|
+
activatedRules.forEach(rule => {
|
|
61
|
+
if (rule.id) {
|
|
62
|
+
if (rule.id.startsWith('S') && rule.severity === 'critical') {
|
|
63
|
+
allActivatedRules[rule.id] = 'error';
|
|
64
|
+
} else {
|
|
65
|
+
allActivatedRules[rule.id] = 'warn';
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
const additionalPresets = {
|
|
71
|
+
beginner: {
|
|
72
|
+
name: "@sun/sunlint/beginner",
|
|
73
|
+
description: "Beginner-friendly configuration with warnings only",
|
|
74
|
+
rules: beginnerRules,
|
|
75
|
+
categories: {
|
|
76
|
+
quality: "warn",
|
|
77
|
+
security: "warn",
|
|
78
|
+
logging: "warn",
|
|
79
|
+
naming: "info",
|
|
80
|
+
validation: "warn"
|
|
81
|
+
},
|
|
82
|
+
languages: ["typescript"],
|
|
83
|
+
exclude: ["**/node_modules/**", "**/build/**", "**/dist/**", "**/*.generated.*", "**/*.min.*"],
|
|
84
|
+
metadata: {
|
|
85
|
+
totalRules: Object.keys(beginnerRules).length,
|
|
86
|
+
approach: "beginner-friendly",
|
|
87
|
+
source: "selected core rules",
|
|
88
|
+
lastUpdated: new Date().toISOString(),
|
|
89
|
+
version: "2.0.0"
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
ci: {
|
|
93
|
+
name: "@sun/sunlint/ci",
|
|
94
|
+
description: "Configuration optimized for CI/CD pipelines",
|
|
95
|
+
rules: ciRules,
|
|
96
|
+
categories: {
|
|
97
|
+
quality: "error",
|
|
98
|
+
security: "error",
|
|
99
|
+
logging: "error",
|
|
100
|
+
naming: "off",
|
|
101
|
+
validation: "error"
|
|
102
|
+
},
|
|
103
|
+
languages: ["typescript", "dart"],
|
|
104
|
+
exclude: ["**/node_modules/**", "**/build/**", "**/dist/**", "**/*.generated.*", "**/*.min.*"],
|
|
105
|
+
metadata: {
|
|
106
|
+
totalRules: Object.keys(ciRules).length,
|
|
107
|
+
approach: "ci-optimized",
|
|
108
|
+
source: "critical rules only",
|
|
109
|
+
lastUpdated: new Date().toISOString(),
|
|
110
|
+
version: "2.0.0"
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
strict: {
|
|
114
|
+
name: "@sun/sunlint/strict",
|
|
115
|
+
description: "Strict configuration for production projects",
|
|
116
|
+
rules: strictRules,
|
|
117
|
+
categories: {
|
|
118
|
+
quality: "error",
|
|
119
|
+
security: "error",
|
|
120
|
+
logging: "error",
|
|
121
|
+
naming: "warn",
|
|
122
|
+
validation: "error"
|
|
123
|
+
},
|
|
124
|
+
languages: ["typescript", "dart", "kotlin"],
|
|
125
|
+
exclude: ["**/node_modules/**", "**/build/**", "**/dist/**", "**/*.generated.*", "**/*.min.*"],
|
|
126
|
+
metadata: {
|
|
127
|
+
totalRules: Object.keys(strictRules).length,
|
|
128
|
+
approach: "strict",
|
|
129
|
+
source: "core rules as errors",
|
|
130
|
+
lastUpdated: new Date().toISOString(),
|
|
131
|
+
version: "2.0.0"
|
|
132
|
+
}
|
|
133
|
+
},
|
|
134
|
+
maintainability: {
|
|
135
|
+
name: "@sun/sunlint/maintainability",
|
|
136
|
+
description: "Maintainability and clean code focused configuration",
|
|
137
|
+
rules: maintainabilityRules,
|
|
138
|
+
categories: {
|
|
139
|
+
maintainability: "warn",
|
|
140
|
+
design: "warn"
|
|
141
|
+
},
|
|
142
|
+
languages: ["typescript", "javascript", "dart", "java", "kotlin", "swift"],
|
|
143
|
+
exclude: ["**/node_modules/**", "**/build/**", "**/dist/**", "**/*.generated.*", "**/*.min.*"],
|
|
144
|
+
metadata: {
|
|
145
|
+
totalRules: Object.keys(maintainabilityRules).length,
|
|
146
|
+
approach: "maintainability-focused",
|
|
147
|
+
source: "maintainability principle rules",
|
|
148
|
+
lastUpdated: new Date().toISOString(),
|
|
149
|
+
version: "2.0.0"
|
|
150
|
+
}
|
|
151
|
+
},
|
|
152
|
+
performance: {
|
|
153
|
+
name: "@sun/sunlint/performance",
|
|
154
|
+
description: "Performance-focused configuration for optimization",
|
|
155
|
+
rules: performanceRules,
|
|
156
|
+
categories: {
|
|
157
|
+
performance: "warn"
|
|
158
|
+
},
|
|
159
|
+
languages: ["typescript", "javascript", "dart", "java", "kotlin", "swift"],
|
|
160
|
+
exclude: ["**/node_modules/**", "**/build/**", "**/dist/**", "**/*.generated.*", "**/*.min.*"],
|
|
161
|
+
metadata: {
|
|
162
|
+
totalRules: Object.keys(performanceRules).length,
|
|
163
|
+
approach: "performance-focused",
|
|
164
|
+
source: "performance principle rules",
|
|
165
|
+
lastUpdated: new Date().toISOString(),
|
|
166
|
+
version: "2.0.0"
|
|
167
|
+
}
|
|
168
|
+
},
|
|
169
|
+
all: {
|
|
170
|
+
name: "@sun/sunlint/all",
|
|
171
|
+
description: "Comprehensive configuration with all activated rules from core files",
|
|
172
|
+
rules: allActivatedRules,
|
|
173
|
+
categories: {
|
|
174
|
+
quality: "warn",
|
|
175
|
+
security: "error",
|
|
176
|
+
performance: "warn",
|
|
177
|
+
maintainability: "warn",
|
|
178
|
+
testability: "warn",
|
|
179
|
+
documentation: "warn"
|
|
180
|
+
},
|
|
181
|
+
languages: ["typescript", "javascript", "dart", "java", "kotlin", "swift"],
|
|
182
|
+
exclude: ["**/node_modules/**", "**/build/**", "**/dist/**", "**/*.generated.*", "**/*.min.*"],
|
|
183
|
+
metadata: {
|
|
184
|
+
totalRules: Object.keys(allActivatedRules).length,
|
|
185
|
+
removedRules: 0,
|
|
186
|
+
approach: "comprehensive-activated-only",
|
|
187
|
+
source: "common-en.md + security-en.md (activated only)",
|
|
188
|
+
lastUpdated: new Date().toISOString(),
|
|
189
|
+
version: "2.0.0"
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
// Write additional preset files
|
|
195
|
+
Object.entries(additionalPresets).forEach(([name, config]) => {
|
|
196
|
+
const filePath = `../config/presets/${name}.json`;
|
|
197
|
+
fs.writeFileSync(filePath, JSON.stringify(config, null, 2));
|
|
198
|
+
console.log(`ā
Generated ${filePath} (${Object.keys(config.rules).length} rules)`);
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
console.log('\n=== ADDITIONAL PRESET GENERATION COMPLETE ===');
|
|
202
|
+
console.log(`šÆ Total presets: ${Object.keys(additionalPresets).length + 3} (including recommended, security, quality)`);
|