svger-cli 4.0.1 → 4.0.3
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 +230 -0
- package/README.md +27 -27
- package/dist/builder.d.ts +6 -3
- package/dist/builder.js +34 -24
- package/dist/cli.js +122 -10
- package/dist/config.d.ts +8 -2
- package/dist/config.js +17 -124
- package/dist/core/enhanced-plugin-manager.d.ts +1 -0
- package/dist/core/enhanced-plugin-manager.js +37 -11
- package/dist/core/framework-templates.js +4 -0
- package/dist/core/logger.js +8 -4
- package/dist/core/performance-engine.js +16 -3
- package/dist/core/style-compiler.js +6 -7
- package/dist/core/template-manager.js +18 -14
- package/dist/index.d.ts +1 -2
- package/dist/index.js +8 -2
- package/dist/integrations/jest-preset.js +30 -2
- package/dist/lock.js +1 -1
- package/dist/optimizers/basic-cleaner.js +4 -0
- package/dist/optimizers/path-parser.js +199 -115
- package/dist/optimizers/path-simplifier.js +27 -24
- package/dist/optimizers/remove-unused-defs.js +16 -0
- package/dist/optimizers/shape-conversion.js +22 -27
- package/dist/optimizers/style-optimizer.js +5 -0
- package/dist/optimizers/svg-tree-parser.js +4 -0
- package/dist/optimizers/transform-collapsing.js +11 -15
- package/dist/optimizers/transform-optimizer.js +20 -21
- package/dist/optimizers/types.js +64 -74
- package/dist/plugins/gradient-optimizer.js +4 -0
- package/dist/processors/svg-processor.js +28 -10
- package/dist/services/config.js +28 -11
- package/dist/services/file-watcher.js +8 -3
- package/dist/services/svg-service.d.ts +1 -1
- package/dist/services/svg-service.js +24 -11
- package/dist/utils/native.d.ts +0 -1
- package/dist/utils/native.js +6 -14
- package/dist/utils/visual-diff.js +7 -2
- package/dist/watch.js +4 -3
- package/docs/ERROR-HANDLING-STANDARD.md +111 -0
- package/docs/OPTIONAL-DEPENDENCIES.md +1 -1
- package/package.json +1 -1
package/dist/utils/native.js
CHANGED
|
@@ -62,7 +62,6 @@ export class FileSystem {
|
|
|
62
62
|
static _readdir = promisify(fs.readdir);
|
|
63
63
|
static _stat = promisify(fs.stat);
|
|
64
64
|
static _mkdir = promisify(fs.mkdir);
|
|
65
|
-
static _rmdir = promisify(fs.rmdir);
|
|
66
65
|
static _unlink = promisify(fs.unlink);
|
|
67
66
|
static async exists(path) {
|
|
68
67
|
try {
|
|
@@ -94,18 +93,7 @@ export class FileSystem {
|
|
|
94
93
|
}
|
|
95
94
|
static async removeDir(dirPath) {
|
|
96
95
|
try {
|
|
97
|
-
|
|
98
|
-
for (const file of files) {
|
|
99
|
-
const filePath = `${dirPath}/${file}`;
|
|
100
|
-
const stats = await this._stat(filePath);
|
|
101
|
-
if (stats.isDirectory()) {
|
|
102
|
-
await this.removeDir(filePath);
|
|
103
|
-
}
|
|
104
|
-
else {
|
|
105
|
-
await this._unlink(filePath);
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
await this._rmdir(dirPath);
|
|
96
|
+
await fs.promises.rm(dirPath, { recursive: true, force: true });
|
|
109
97
|
}
|
|
110
98
|
catch (error) {
|
|
111
99
|
if (error.code !== 'ENOENT') {
|
|
@@ -311,10 +299,14 @@ export class FileWatcher {
|
|
|
311
299
|
this.emit(eventType, `${path}/${filename}`);
|
|
312
300
|
}
|
|
313
301
|
});
|
|
302
|
+
watcher.on('error', error => {
|
|
303
|
+
this.emit('error', error);
|
|
304
|
+
});
|
|
314
305
|
this.watchers.push(watcher);
|
|
315
306
|
}
|
|
316
307
|
catch (error) {
|
|
317
|
-
|
|
308
|
+
// Emit error event so consumers can handle it
|
|
309
|
+
this.emit('error', error);
|
|
318
310
|
}
|
|
319
311
|
return this;
|
|
320
312
|
}
|
|
@@ -81,17 +81,22 @@ export class VisualDiffError extends Error {
|
|
|
81
81
|
export async function renderSVG(svgContent, config) {
|
|
82
82
|
await loadVisualDiffDependencies();
|
|
83
83
|
const renderConfig = { ...DEFAULT_RENDER_CONFIG, ...config };
|
|
84
|
+
const RENDER_TIMEOUT_MS = 30000; // 30 seconds
|
|
84
85
|
try {
|
|
85
86
|
// Create SVG buffer
|
|
86
87
|
const svgBuffer = Buffer.from(svgContent, 'utf-8');
|
|
87
|
-
// Render to PNG using sharp
|
|
88
|
-
const
|
|
88
|
+
// Render to PNG using sharp with timeout protection
|
|
89
|
+
const renderPromise = sharp(svgBuffer, { density: renderConfig.density })
|
|
89
90
|
.resize(renderConfig.width, renderConfig.height, {
|
|
90
91
|
fit: 'contain',
|
|
91
92
|
background: renderConfig.background,
|
|
92
93
|
})
|
|
93
94
|
.png()
|
|
94
95
|
.toBuffer();
|
|
96
|
+
const timeoutPromise = new Promise((_resolve, reject) => {
|
|
97
|
+
setTimeout(() => reject(new Error(`Render timeout after ${RENDER_TIMEOUT_MS}ms`)), RENDER_TIMEOUT_MS);
|
|
98
|
+
});
|
|
99
|
+
const pngBuffer = await Promise.race([renderPromise, timeoutPromise]);
|
|
95
100
|
return pngBuffer;
|
|
96
101
|
}
|
|
97
102
|
catch (error) {
|
package/dist/watch.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import path from 'path';
|
|
2
2
|
import { generateSVG } from './builder.js';
|
|
3
3
|
import { isLocked } from './lock.js';
|
|
4
|
-
import { FileSystem, FileWatcher } from './utils/native.js';
|
|
4
|
+
import { FileSystem, FileWatcher, toPascalCase } from './utils/native.js';
|
|
5
5
|
/**
|
|
6
6
|
* Watches a source folder for changes to SVG files and automatically
|
|
7
7
|
* rebuilds React components when SVGs are added, modified, or deleted.
|
|
@@ -59,8 +59,9 @@ export async function watchSVGs(config) {
|
|
|
59
59
|
await generateSVG({ svgFile: filePath, outDir });
|
|
60
60
|
}
|
|
61
61
|
else {
|
|
62
|
-
// File was deleted
|
|
63
|
-
const
|
|
62
|
+
// File was deleted — use PascalCase to match the generated component filename
|
|
63
|
+
const baseName = path.basename(filePath, '.svg');
|
|
64
|
+
const componentName = toPascalCase(baseName);
|
|
64
65
|
const outFile = path.join(outDir, `${componentName}.tsx`);
|
|
65
66
|
if (await FileSystem.exists(outFile)) {
|
|
66
67
|
await FileSystem.unlink(outFile);
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# Error Handling Standards
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
This document establishes standardized error handling patterns for SVGER-CLI v4.0.3+ to ensure consistency, proper error propagation, and appropriate user feedback.
|
|
5
|
+
|
|
6
|
+
## Standard Patterns
|
|
7
|
+
|
|
8
|
+
### 1. CLI Command Error Handling (Process Exit Required)
|
|
9
|
+
**Pattern:** Log error + exit with code 1
|
|
10
|
+
```typescript
|
|
11
|
+
try {
|
|
12
|
+
await someOperation();
|
|
13
|
+
} catch (error) {
|
|
14
|
+
logger.error('Operation failed:', error);
|
|
15
|
+
process.exit(1);
|
|
16
|
+
}
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### 2. Service Method Error Handling (Propagate to Caller)
|
|
20
|
+
**Pattern:** Log error + throw
|
|
21
|
+
```typescript
|
|
22
|
+
try {
|
|
23
|
+
const result = await operation();
|
|
24
|
+
return result;
|
|
25
|
+
} catch (error) {
|
|
26
|
+
logger.error('Failed to perform operation:', error);
|
|
27
|
+
throw error;
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### 3. Background/Async Error Handling (Non-blocking)
|
|
32
|
+
**Pattern:** Log error + return error state
|
|
33
|
+
```typescript
|
|
34
|
+
try {
|
|
35
|
+
await backgroundTask();
|
|
36
|
+
} catch (error) {
|
|
37
|
+
logger.error('Background task failed:', error);
|
|
38
|
+
return { success: false, error };
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### 4. Batch Processing Error Handling (Continue on Individual Failures)
|
|
43
|
+
**Pattern:** Log individual errors + collect results
|
|
44
|
+
```typescript
|
|
45
|
+
const results = [];
|
|
46
|
+
for (const item of items) {
|
|
47
|
+
try {
|
|
48
|
+
const result = await processItem(item);
|
|
49
|
+
results.push({ success: true, data: result });
|
|
50
|
+
} catch (error) {
|
|
51
|
+
logger.error(`Failed to process ${item}:`, error);
|
|
52
|
+
results.push({ success: false, error });
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### 5. Plugin Error Handling (Isolated Failure)
|
|
58
|
+
**Pattern:** Log error + skip plugin + continue pipeline
|
|
59
|
+
```typescript
|
|
60
|
+
try {
|
|
61
|
+
await plugin.execute();
|
|
62
|
+
} catch (error) {
|
|
63
|
+
logger.error(`Plugin "${plugin.name}" failed:`, (error as Error).message);
|
|
64
|
+
// Continue with next plugin
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Error Types by Severity
|
|
69
|
+
|
|
70
|
+
### Critical (Process Exit)
|
|
71
|
+
- Configuration file corruption
|
|
72
|
+
- Permission denied for required directories
|
|
73
|
+
- Invalid CLI arguments
|
|
74
|
+
|
|
75
|
+
### High (Throw Error)
|
|
76
|
+
- File not found for specific operation
|
|
77
|
+
- Invalid SVG syntax
|
|
78
|
+
- Build failures
|
|
79
|
+
|
|
80
|
+
### Medium (Log + Return Error State)
|
|
81
|
+
- Individual file processing failures in batch
|
|
82
|
+
- Plugin execution failures
|
|
83
|
+
- Optional feature failures (visual validation)
|
|
84
|
+
|
|
85
|
+
### Low (Log Warning + Continue)
|
|
86
|
+
- Missing optional configuration
|
|
87
|
+
- Deprecation warnings
|
|
88
|
+
- Non-critical file operations
|
|
89
|
+
|
|
90
|
+
## Implementation Status
|
|
91
|
+
|
|
92
|
+
### ✅ Completed
|
|
93
|
+
- CLI commands properly exit on error
|
|
94
|
+
- Service methods properly propagate errors
|
|
95
|
+
- Batch processing collects individual failures
|
|
96
|
+
|
|
97
|
+
### 🔄 Needs Review
|
|
98
|
+
- Ensure all catch blocks follow appropriate pattern for their context
|
|
99
|
+
- Verify error messages are clear and actionable
|
|
100
|
+
- Check that error context is preserved in stack traces
|
|
101
|
+
|
|
102
|
+
## Related Fixes
|
|
103
|
+
- Bug #2: Added process.exit(1) in config command
|
|
104
|
+
- Bug #12: Plugin registration now throws on duplicate names
|
|
105
|
+
- Bug #17: Added CLI argument validation with early exit
|
|
106
|
+
|
|
107
|
+
## Next Steps
|
|
108
|
+
1. Audit all catch blocks for consistency
|
|
109
|
+
2. Ensure error messages are user-friendly
|
|
110
|
+
3. Add error codes for common scenarios
|
|
111
|
+
4. Consider using error-handler.ts more consistently
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svger-cli",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.3",
|
|
4
4
|
"description": "Enterprise-grade SVG to component converter with advanced plugin system, visual diff testing, and official framework integrations. Supporting React, React Native, Vue, Angular, Svelte, Solid, Lit, Preact & Vanilla. Features TypeScript, HMR, optimization pipeline, and extensible architecture.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|