@sun-asterisk/sunlint 1.3.16 → 1.3.17
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 +3 -3
- package/config/rules/enhanced-rules-registry.json +40 -20
- package/core/cli-action-handler.js +2 -2
- package/core/config-merger.js +28 -6
- package/core/constants/defaults.js +1 -1
- package/core/file-targeting-service.js +72 -4
- package/core/output-service.js +21 -4
- package/engines/heuristic-engine.js +5 -0
- package/package.json +1 -1
- package/rules/common/C002_no_duplicate_code/README.md +115 -0
- package/rules/common/C002_no_duplicate_code/analyzer.js +615 -219
- package/rules/common/C002_no_duplicate_code/test-cases/api-handlers.ts +64 -0
- package/rules/common/C002_no_duplicate_code/test-cases/data-processor.ts +46 -0
- package/rules/common/C002_no_duplicate_code/test-cases/good-example.tsx +40 -0
- package/rules/common/C002_no_duplicate_code/test-cases/product-service.ts +57 -0
- package/rules/common/C002_no_duplicate_code/test-cases/user-service.ts +49 -0
- package/rules/common/C008/analyzer.js +40 -0
- package/rules/common/C008/config.json +20 -0
- package/rules/common/C008/ts-morph-analyzer.js +1067 -0
- package/rules/common/C018_no_throw_generic_error/analyzer.js +1 -1
- package/rules/common/C018_no_throw_generic_error/symbol-based-analyzer.js +27 -3
- package/rules/common/C024_no_scatter_hardcoded_constants/symbol-based-analyzer.js +504 -162
- package/rules/common/C029_catch_block_logging/analyzer.js +499 -89
- package/rules/common/C033_separate_service_repository/README.md +131 -20
- package/rules/common/C033_separate_service_repository/analyzer.js +1 -1
- package/rules/common/C033_separate_service_repository/symbol-based-analyzer.js +417 -274
- package/rules/common/C041_no_sensitive_hardcode/analyzer.js +144 -254
- package/rules/common/C041_no_sensitive_hardcode/config.json +50 -0
- package/rules/common/C041_no_sensitive_hardcode/symbol-based-analyzer.js +575 -0
- package/rules/common/C067_no_hardcoded_config/analyzer.js +17 -16
- package/rules/common/C067_no_hardcoded_config/symbol-based-analyzer.js +3477 -659
- package/rules/docs/C002_no_duplicate_code.md +276 -11
- package/rules/index.js +5 -1
- package/rules/security/S006_no_plaintext_recovery_codes/analyzer.js +266 -88
- package/rules/security/S006_no_plaintext_recovery_codes/symbol-based-analyzer.js +805 -0
- package/rules/security/S010_no_insecure_encryption/README.md +78 -0
- package/rules/security/S010_no_insecure_encryption/analyzer.js +463 -398
- package/rules/security/S013_tls_enforcement/README.md +51 -0
- package/rules/security/S013_tls_enforcement/analyzer.js +99 -0
- package/rules/security/S013_tls_enforcement/config.json +41 -0
- package/rules/security/S013_tls_enforcement/symbol-based-analyzer.js +339 -0
- package/rules/security/S014_tls_version_enforcement/README.md +354 -0
- package/rules/security/S014_tls_version_enforcement/analyzer.js +118 -0
- package/rules/security/S014_tls_version_enforcement/config.json +56 -0
- package/rules/security/S014_tls_version_enforcement/symbol-based-analyzer.js +194 -0
- package/rules/security/S055_content_type_validation/analyzer.js +121 -279
- package/rules/security/S055_content_type_validation/symbol-based-analyzer.js +346 -0
- package/rules/tests/C002_no_duplicate_code.test.js +111 -22
- package/rules/common/C029_catch_block_logging/analyzer-smart-pipeline.js +0 -755
- package/rules/common/C041_no_sensitive_hardcode/ast-analyzer.js +0 -296
|
@@ -2,23 +2,38 @@
|
|
|
2
2
|
|
|
3
3
|
## Rule Description
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
**Mục tiêu:** Tách rõ ràng business logic và data access logic trong kiến trúc ứng dụng
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
### Nguyên tắc
|
|
8
|
+
|
|
9
|
+
- ✅ **Repository** chỉ chứa các phương thức truy vấn dữ liệu cơ bản (CRUD)
|
|
10
|
+
- ✅ **Service** chứa business logic và sử dụng Repository để truy vấn dữ liệu
|
|
11
|
+
- ✅ Mỗi Service nên có một Repository tương ứng
|
|
12
|
+
- ✅ Sử dụng dependency injection để inject Repository vào Service
|
|
13
|
+
- ❌ Tránh viết business logic trong Repository
|
|
14
|
+
- ❌ Service không nên trực tiếp gọi database/ORM
|
|
15
|
+
|
|
16
|
+
### Lợi ích
|
|
17
|
+
|
|
18
|
+
- 🔄 Tăng khả năng tái sử dụng và test
|
|
19
|
+
- 🎯 Tách biệt rõ ràng giữa business logic và data access
|
|
20
|
+
- 🔧 Dễ dàng thay đổi implementation của data access layer
|
|
21
|
+
- 📈 Tăng tính maintainable của code
|
|
22
|
+
- ✨ Tuân thủ nguyên tắc Single Responsibility
|
|
9
23
|
|
|
10
24
|
## Architecture
|
|
11
25
|
|
|
12
|
-
|
|
26
|
+
Rule này sử dụng **hybrid analysis approach**:
|
|
13
27
|
|
|
14
|
-
1. **Primary: Symbol-based Analysis** (
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
28
|
+
1. **Primary: Symbol-based Analysis** (ts-morph AST)
|
|
29
|
+
- Phân tích semantic và symbol resolution
|
|
30
|
+
- Phát hiện chính xác database operations
|
|
31
|
+
- Kiểm tra dependency injection patterns
|
|
32
|
+
- Phát hiện business logic trong Repository
|
|
18
33
|
|
|
19
34
|
2. **Fallback: Regex-based Analysis**
|
|
20
|
-
- Pattern matching
|
|
21
|
-
-
|
|
35
|
+
- Pattern matching khi symbol analysis không khả dụng
|
|
36
|
+
- Xử lý edge cases và complex code structures
|
|
22
37
|
|
|
23
38
|
## Files Structure
|
|
24
39
|
|
|
@@ -33,20 +48,116 @@ C033_separate_service_repository/
|
|
|
33
48
|
|
|
34
49
|
## What this rule detects
|
|
35
50
|
|
|
36
|
-
### Violations in Service files
|
|
37
|
-
|
|
38
|
-
- Direct ORM operations
|
|
39
|
-
-
|
|
40
|
-
-
|
|
51
|
+
### 🚫 Violations in Service files
|
|
52
|
+
|
|
53
|
+
- Direct database/ORM operations without Repository
|
|
54
|
+
- `findOne()`, `save()`, `update()`, `delete()`, `query()`
|
|
55
|
+
- `createQueryBuilder()`, `getRepository()`, `getConnection()`
|
|
56
|
+
- Service không inject Repository qua constructor
|
|
57
|
+
- Mixed business logic với data access trong cùng method
|
|
58
|
+
|
|
59
|
+
### 🚫 Violations in Repository files
|
|
60
|
+
|
|
61
|
+
- Business logic trong Repository methods
|
|
62
|
+
- Method names chứa: `validate`, `calculate`, `process`, `transform`
|
|
63
|
+
- Logic phức tạp: nhiều if/else, loops (>2 control structures)
|
|
64
|
+
- Business calculations, validations, transformations
|
|
65
|
+
- Complex workflows và business rules
|
|
66
|
+
|
|
67
|
+
### 🚫 Violations in Controller files
|
|
68
|
+
|
|
69
|
+
- Controller trực tiếp gọi database operations
|
|
70
|
+
- Bỏ qua Service layer
|
|
41
71
|
|
|
42
|
-
###
|
|
43
|
-
|
|
44
|
-
-
|
|
45
|
-
-
|
|
72
|
+
### 🚫 Architecture violations
|
|
73
|
+
|
|
74
|
+
- Service và Repository cùng trong một file
|
|
75
|
+
- Không tách biệt concerns rõ ràng
|
|
46
76
|
|
|
47
77
|
## Examples
|
|
48
78
|
|
|
49
|
-
|
|
79
|
+
### ❌ BAD: Service directly accessing database
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
// service-bad.ts
|
|
83
|
+
class UserService {
|
|
84
|
+
async getUser(id: string) {
|
|
85
|
+
// VIOLATION: Direct database access in Service
|
|
86
|
+
return await this.dataSource
|
|
87
|
+
.getRepository(User)
|
|
88
|
+
.findOne({ where: { id } });
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### ✅ GOOD: Service uses Repository
|
|
94
|
+
|
|
95
|
+
```typescript
|
|
96
|
+
// user.service.ts
|
|
97
|
+
class UserService {
|
|
98
|
+
constructor(
|
|
99
|
+
private readonly userRepository: UserRepository // DI
|
|
100
|
+
) {}
|
|
101
|
+
|
|
102
|
+
async getUser(id: string) {
|
|
103
|
+
return await this.userRepository.findById(id);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
async validateAndCreateUser(data: CreateUserDto) {
|
|
107
|
+
// Business logic in Service
|
|
108
|
+
this.validate(data);
|
|
109
|
+
const user = this.transform(data);
|
|
110
|
+
return await this.userRepository.create(user);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// user.repository.ts
|
|
115
|
+
class UserRepository {
|
|
116
|
+
// Only CRUD operations
|
|
117
|
+
async findById(id: string) {
|
|
118
|
+
return await this.db.users.findOne({ where: { id } });
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
async create(user: User) {
|
|
122
|
+
return await this.db.users.save(user);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### ❌ BAD: Repository with business logic
|
|
128
|
+
|
|
129
|
+
```typescript
|
|
130
|
+
// repository-bad.ts
|
|
131
|
+
class UserRepository {
|
|
132
|
+
async validateAndSave(user: User) {
|
|
133
|
+
// VIOLATION: Business logic in Repository
|
|
134
|
+
if (user.age < 18) {
|
|
135
|
+
throw new Error('User must be 18+');
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (!user.email.includes('@')) {
|
|
139
|
+
throw new Error('Invalid email');
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
return await this.save(user);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### ✅ GOOD: Repository only handles data access
|
|
148
|
+
|
|
149
|
+
```typescript
|
|
150
|
+
// repository-good.ts
|
|
151
|
+
class UserRepository {
|
|
152
|
+
// Simple CRUD - no business logic
|
|
153
|
+
async save(user: User) {
|
|
154
|
+
return await this.db.users.save(user);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
async findByEmail(email: string) {
|
|
158
|
+
return await this.db.users.findOne({ where: { email } });
|
|
159
|
+
}
|
|
160
|
+
}
|
|
50
161
|
|
|
51
162
|
- **Violations**: `examples/rule-test-fixtures/rules/C033_separate_service_repository/violations/test-cases.js`
|
|
52
163
|
- **Clean code**: `examples/rule-test-fixtures/rules/C033_separate_service_repository/clean/good-examples.js`
|
|
@@ -82,7 +82,7 @@ class C033Analyzer {
|
|
|
82
82
|
// 1. Try Symbol-based analysis first (primary)
|
|
83
83
|
if (this.config.useSymbolBased && this.semanticEngine?.project) {
|
|
84
84
|
try {
|
|
85
|
-
const sourceFile = this.semanticEngine.project.
|
|
85
|
+
const sourceFile = this.semanticEngine.project.getSourceFile(filePath);
|
|
86
86
|
if (sourceFile) {
|
|
87
87
|
const violations = await this.symbolBasedAnalyzer.analyzeFileWithSymbols(filePath, options);
|
|
88
88
|
|