Skip to content

Commit e406d4a

Browse files
committed
feat: 完善项目功能和文档
- 添加多语言支持(中英文) - 完善curl解析和过滤功能 - 添加历史记录管理 - 添加规则管理和验证 - 完善IndexedDB存储功能 - 添加单元测试 - 完善项目文档(API.md, CHANGELOG.md, CONTRIBUTING.md, DEVELOPMENT.md) - 更新GitHub Actions部署配置
1 parent 2015d9b commit e406d4a

20 files changed

+2227
-68
lines changed

.github/workflows/deploy.yml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,13 @@ jobs:
3636

3737
- name: 安装依赖
3838
run: npm ci
39-
39+
40+
- name: 运行代码检查
41+
run: npm run lint
42+
43+
- name: 运行测试
44+
run: npm run test:run
45+
4046
- name: 构建项目
4147
run: npm run build
4248

API.md

Lines changed: 377 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,377 @@
1+
# API Documentation
2+
3+
This document describes the core APIs and interfaces used in the cURL Filter application.
4+
5+
## 🔧 Core APIs
6+
7+
### CurlParser
8+
9+
Parses cURL commands into structured data.
10+
11+
```typescript
12+
import { parseCurl, type ParsedCurl } from './utils/curlParser';
13+
14+
// Parse a cURL command
15+
const result: ParsedCurl = parseCurl(curlCommand);
16+
```
17+
18+
#### ParsedCurl Interface
19+
20+
```typescript
21+
interface ParsedCurl {
22+
url: string; // Request URL
23+
method: string; // HTTP method (GET, POST, etc.)
24+
headers: Record<string, string>; // HTTP headers
25+
queryParams: Record<string, string>; // URL query parameters
26+
formData: Record<string, string>; // Form data
27+
jsonBody: any; // JSON request body
28+
data?: string; // Raw data (for backward compatibility)
29+
otherOptions: string[]; // Other cURL options
30+
}
31+
```
32+
33+
#### Example Usage
34+
35+
```typescript
36+
const curlCommand = `curl 'https://api.example.com/users' \\
37+
-H 'authorization: Bearer token123' \\
38+
-H 'content-type: application/json' \\
39+
-d '{"name": "John"}'`;
40+
41+
const parsed = parseCurl(curlCommand);
42+
console.log(parsed.url); // 'https://api.example.com/users'
43+
console.log(parsed.method); // 'GET'
44+
console.log(parsed.headers); // { authorization: 'Bearer token123', ... }
45+
console.log(parsed.jsonBody); // { name: 'John' }
46+
```
47+
48+
### FilterEngine
49+
50+
Applies filtering rules to parsed cURL data.
51+
52+
```typescript
53+
import { FilterEngine } from './utils/filterEngine';
54+
import type { FilterRule, FilterContext, FilterResult } from './types/filterRules';
55+
56+
// Create filter engine
57+
const engine = new FilterEngine();
58+
59+
// Set rules
60+
engine.setRules(rules);
61+
62+
// Apply filters
63+
const result: FilterResult = engine.applyFilters(context);
64+
```
65+
66+
#### FilterRule Interface
67+
68+
```typescript
69+
interface FilterRule {
70+
id: string; // Unique identifier
71+
name: string; // Rule name
72+
action: FilterAction; // Filter action
73+
target: FilterTarget; // Target type
74+
matchMode: MatchMode; // Match pattern
75+
matchValue: string; // Match value
76+
priority: number; // Priority (0-100)
77+
enabled: boolean; // Whether rule is enabled
78+
description?: string; // Optional description
79+
createdAt: string; // Creation timestamp
80+
updatedAt: string; // Last update timestamp
81+
}
82+
```
83+
84+
#### FilterAction Types
85+
86+
```typescript
87+
type FilterAction = 'delete' | 'delete_all' | 'keep' | 'keep_all';
88+
```
89+
90+
- `delete`: Remove matching items
91+
- `delete_all`: Remove all items (ignore match value)
92+
- `keep`: Keep only matching items
93+
- `keep_all`: Keep all items (ignore match value)
94+
95+
#### FilterTarget Types
96+
97+
```typescript
98+
type FilterTarget = 'headers' | 'query_params' | 'form_data' | 'json_body';
99+
```
100+
101+
#### MatchMode Types
102+
103+
```typescript
104+
type MatchMode = 'exact' | 'contains' | 'starts_with' | 'ends_with' | 'regex';
105+
```
106+
107+
#### FilterContext Interface
108+
109+
```typescript
110+
interface FilterContext {
111+
headers: Record<string, string>; // HTTP headers
112+
queryParams: Record<string, string>; // Query parameters
113+
formData: Record<string, string>; // Form data
114+
jsonBody: any; // JSON body
115+
url: string; // Request URL
116+
method: string; // HTTP method
117+
}
118+
```
119+
120+
#### FilterResult Interface
121+
122+
```typescript
123+
interface FilterResult {
124+
headers: Record<string, string>; // Filtered headers
125+
queryParams: Record<string, string>; // Filtered query parameters
126+
formData: Record<string, string>; // Filtered form data
127+
jsonBody: any; // Filtered JSON body
128+
appliedRules: string[]; // Applied rule IDs
129+
warnings: string[]; // Warning messages
130+
}
131+
```
132+
133+
### RuleValidation
134+
135+
Validates filter rules and provides error feedback.
136+
137+
```typescript
138+
import { validateRule, validateRuleField } from './utils/ruleValidation';
139+
140+
// Validate complete rule
141+
const validation = validateRule(rule);
142+
if (!validation.isValid) {
143+
console.log('Errors:', validation.errors);
144+
console.log('Warnings:', validation.warnings);
145+
}
146+
147+
// Validate specific field
148+
const fieldErrors = validateRuleField('matchValue', value, rule);
149+
```
150+
151+
#### RuleValidationResult Interface
152+
153+
```typescript
154+
interface RuleValidationResult {
155+
isValid: boolean; // Whether rule is valid
156+
errors: string[]; // Error messages
157+
warnings: string[]; // Warning messages
158+
}
159+
```
160+
161+
### Storage APIs
162+
163+
#### Rule Storage
164+
165+
```typescript
166+
import { saveRules, loadRules } from './utils/ruleStorage';
167+
168+
// Save rules
169+
const success = await saveRules(rules);
170+
171+
// Load rules
172+
const rules = await loadRules();
173+
```
174+
175+
#### History Storage
176+
177+
```typescript
178+
import {
179+
saveHistoryEntry,
180+
getHistoryEntries,
181+
deleteHistoryEntry
182+
} from './utils/indexedDBStorage';
183+
184+
// Save history entry
185+
await saveHistoryEntry(inputCurl, outputCurl, appliedRules, filterResult);
186+
187+
// Get history entries
188+
const entries = await getHistoryEntries({
189+
limit: 10,
190+
offset: 0,
191+
sortBy: 'timestamp',
192+
sortOrder: 'desc'
193+
});
194+
195+
// Delete history entry
196+
await deleteHistoryEntry(entryId);
197+
```
198+
199+
## 🎨 Component APIs
200+
201+
### CurlFilter Component
202+
203+
Main application component with the following props:
204+
205+
```typescript
206+
interface CurlFilterProps {
207+
// No props - self-contained component
208+
}
209+
```
210+
211+
### RuleManager Component
212+
213+
```typescript
214+
interface RuleManagerProps {
215+
open: boolean; // Whether dialog is open
216+
onClose: () => void; // Close handler
217+
rules: FilterRule[]; // Current rules
218+
onRulesChange: (rules: FilterRule[]) => void; // Rules change handler
219+
}
220+
```
221+
222+
### HistoryManager Component
223+
224+
```typescript
225+
interface HistoryManagerProps {
226+
open: boolean; // Whether dialog is open
227+
onClose: () => void; // Close handler
228+
onSelectEntry?: (entry: HistoryEntry) => void; // Entry selection handler
229+
}
230+
```
231+
232+
## 🌐 Internationalization API
233+
234+
### Translation Hook
235+
236+
```typescript
237+
import { useTranslation } from 'react-i18next';
238+
239+
function MyComponent() {
240+
const { t, i18n } = useTranslation();
241+
242+
// Simple translation
243+
const title = t('app.title');
244+
245+
// Translation with parameters
246+
const message = t('messages.filterComplete', { count: 5 });
247+
248+
// Change language
249+
i18n.changeLanguage('zh');
250+
251+
return <div>{title}</div>;
252+
}
253+
```
254+
255+
### Translation Keys Structure
256+
257+
```typescript
258+
interface TranslationKeys {
259+
app: {
260+
title: string;
261+
subtitle: string;
262+
};
263+
buttons: {
264+
save: string;
265+
cancel: string;
266+
// ... more buttons
267+
};
268+
messages: {
269+
success: string;
270+
error: string;
271+
// ... more messages
272+
};
273+
// ... more sections
274+
}
275+
```
276+
277+
## 🔍 Utility Functions
278+
279+
### Rule Templates
280+
281+
```typescript
282+
import { BUILT_IN_TEMPLATES, createRuleFromTemplate } from './utils/ruleTemplates';
283+
284+
// Get available templates
285+
const templates = BUILT_IN_TEMPLATES;
286+
287+
// Create rules from template
288+
const rules = createRuleFromTemplate(template);
289+
```
290+
291+
### Rule Generation
292+
293+
```typescript
294+
import { generateRuleId, createDefaultRule } from './utils/ruleValidation';
295+
296+
// Generate unique rule ID
297+
const id = generateRuleId();
298+
299+
// Create default rule
300+
const rule = createDefaultRule({
301+
name: 'My Custom Rule',
302+
action: 'delete',
303+
target: 'headers'
304+
});
305+
```
306+
307+
## 🚨 Error Handling
308+
309+
### Common Error Types
310+
311+
```typescript
312+
// Parse errors
313+
try {
314+
const parsed = parseCurl(invalidCurl);
315+
} catch (error) {
316+
console.error('Parse error:', error.message);
317+
}
318+
319+
// Validation errors
320+
const validation = validateRule(rule);
321+
if (!validation.isValid) {
322+
validation.errors.forEach(error => {
323+
console.error('Validation error:', error);
324+
});
325+
}
326+
327+
// Storage errors
328+
try {
329+
await saveRules(rules);
330+
} catch (error) {
331+
console.error('Storage error:', error);
332+
}
333+
```
334+
335+
### Error Recovery
336+
337+
The application implements graceful error recovery:
338+
339+
1. **Parse Errors**: Show user-friendly error messages
340+
2. **Validation Errors**: Highlight problematic fields
341+
3. **Storage Errors**: Fallback to memory storage
342+
4. **Network Errors**: Retry mechanisms where applicable
343+
344+
## 📊 Performance Considerations
345+
346+
### Debouncing
347+
348+
Input processing is debounced to improve performance:
349+
350+
```typescript
351+
// Auto-filter with 800ms debounce
352+
const autoFilter = useCallback(debounce((curlText: string) => {
353+
// Process input
354+
}, 800), []);
355+
```
356+
357+
### Memoization
358+
359+
Expensive computations are memoized:
360+
361+
```typescript
362+
const processedRules = useMemo(() => {
363+
return rules.filter(rule => rule.enabled)
364+
.sort((a, b) => b.priority - a.priority);
365+
}, [rules]);
366+
```
367+
368+
### Virtual Scrolling
369+
370+
Large lists use virtual scrolling for better performance:
371+
372+
```typescript
373+
// History entries are virtualized for large datasets
374+
const VirtualizedHistoryList = ({ entries }) => {
375+
// Implementation details...
376+
};
377+
```

0 commit comments

Comments
 (0)