svger-cli 1.0.6 → 1.0.7

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.
Files changed (64) hide show
  1. package/CODE_OF_CONDUCT.md +79 -0
  2. package/CONTRIBUTING.md +146 -0
  3. package/LICENSE +21 -0
  4. package/README.md +1862 -73
  5. package/TESTING.md +143 -0
  6. package/cli-framework.test.js +16 -0
  7. package/cli-test-angular/Arrowbenddownleft.component.ts +27 -0
  8. package/cli-test-angular/Vite.component.ts +27 -0
  9. package/cli-test-angular/index.ts +25 -0
  10. package/{my-icons/ArrowBendDownLeft.tsx → cli-test-output/Arrowbenddownleft.vue} +28 -12
  11. package/{my-icons/Vite.tsx → cli-test-output/Vite.vue} +28 -12
  12. package/cli-test-output/index.ts +25 -0
  13. package/cli-test-react/Arrowbenddownleft.tsx +39 -0
  14. package/cli-test-react/Vite.tsx +39 -0
  15. package/cli-test-react/index.ts +25 -0
  16. package/cli-test-svelte/Arrowbenddownleft.svelte +22 -0
  17. package/cli-test-svelte/Vite.svelte +22 -0
  18. package/cli-test-svelte/index.ts +25 -0
  19. package/dist/builder.js +12 -13
  20. package/dist/clean.js +3 -3
  21. package/dist/cli.js +139 -61
  22. package/dist/config.d.ts +1 -1
  23. package/dist/config.js +5 -7
  24. package/dist/lock.js +1 -1
  25. package/dist/templates/ComponentTemplate.d.ts +15 -0
  26. package/dist/templates/ComponentTemplate.js +15 -0
  27. package/dist/watch.d.ts +2 -1
  28. package/dist/watch.js +30 -33
  29. package/docs/ADR-SVG-INTRGRATION-METHODS-002.adr.md +550 -0
  30. package/docs/FRAMEWORK-GUIDE.md +768 -0
  31. package/docs/IMPLEMENTATION-SUMMARY.md +376 -0
  32. package/frameworks.test.js +170 -0
  33. package/package.json +7 -10
  34. package/src/builder.ts +12 -13
  35. package/src/clean.ts +3 -3
  36. package/src/cli.ts +148 -59
  37. package/src/config.ts +5 -6
  38. package/src/core/error-handler.ts +303 -0
  39. package/src/core/framework-templates.ts +428 -0
  40. package/src/core/logger.ts +104 -0
  41. package/src/core/performance-engine.ts +327 -0
  42. package/src/core/plugin-manager.ts +228 -0
  43. package/src/core/style-compiler.ts +605 -0
  44. package/src/core/template-manager.ts +619 -0
  45. package/src/index.ts +235 -0
  46. package/src/lock.ts +1 -1
  47. package/src/processors/svg-processor.ts +288 -0
  48. package/src/services/config.ts +241 -0
  49. package/src/services/file-watcher.ts +218 -0
  50. package/src/services/svg-service.ts +468 -0
  51. package/src/types/index.ts +169 -0
  52. package/src/utils/native.ts +352 -0
  53. package/src/watch.ts +36 -36
  54. package/test-output-mulit/TestIcon-angular-module.component.ts +26 -0
  55. package/test-output-mulit/TestIcon-angular-standalone.component.ts +27 -0
  56. package/test-output-mulit/TestIcon-lit.ts +35 -0
  57. package/test-output-mulit/TestIcon-preact.tsx +38 -0
  58. package/test-output-mulit/TestIcon-react.tsx +35 -0
  59. package/test-output-mulit/TestIcon-solid.tsx +27 -0
  60. package/test-output-mulit/TestIcon-svelte.svelte +22 -0
  61. package/test-output-mulit/TestIcon-vanilla.ts +37 -0
  62. package/test-output-mulit/TestIcon-vue-composition.vue +33 -0
  63. package/test-output-mulit/TestIcon-vue-options.vue +31 -0
  64. package/tsconfig.json +11 -9
package/src/index.ts ADDED
@@ -0,0 +1,235 @@
1
+ /**
2
+ * SVGER-CLI - Zero-Dependency SVG to React Component Generator
3
+ *
4
+ * A high-performance, framework-agnostic SVG processing toolkit with enterprise-grade
5
+ * architecture and comprehensive styling capabilities.
6
+ *
7
+ * @version 2.0.0
8
+ * @author SVGER-CLI Development Team
9
+ * @license MIT
10
+ */
11
+
12
+ // ============================================================================
13
+ // CORE SERVICES
14
+ // ============================================================================
15
+
16
+ /**
17
+ * Logger Service - Professional logging with configurable levels and color formatting
18
+ * Provides: debug, info, warn, error, success methods with timestamp and context
19
+ */
20
+ export { LoggerService, logger } from './core/logger.js';
21
+
22
+ /**
23
+ * Configuration Management Service - Centralized configuration with validation and caching
24
+ * Provides: config loading, validation, defaults, and file-based persistence
25
+ */
26
+ export { ConfigService, configService } from './services/config.js';
27
+
28
+ /**
29
+ * Error Handler - Comprehensive error management with recovery strategies
30
+ * Provides: structured error handling, recovery mechanisms, and user-friendly messages
31
+ */
32
+ export { SVGErrorHandler, errorHandler, withErrorHandling, handleErrors } from './core/error-handler.js';
33
+
34
+ // ============================================================================
35
+ // PROCESSING ENGINES
36
+ // ============================================================================
37
+
38
+ /**
39
+ * SVG Processor - Core SVG content processing and React component generation
40
+ * Provides: SVG parsing, optimization, React component generation, and batch processing
41
+ */
42
+ export { SVGProcessor, svgProcessor } from './processors/svg-processor.js';
43
+
44
+ /**
45
+ * Performance Engine - Advanced optimization for batch processing and parallel execution
46
+ * Provides: batch processing, caching, memory optimization, and performance monitoring
47
+ */
48
+ export { PerformanceEngine, performanceEngine } from './core/performance-engine.js';
49
+
50
+ /**
51
+ * Style Compiler - Comprehensive styling system with responsive design and theming
52
+ * Provides: CSS generation, theme management, responsive values, and style optimization
53
+ */
54
+ export { SVGStyleCompiler, styleCompiler } from './core/style-compiler.js';
55
+
56
+ // ============================================================================
57
+ // TEMPLATE SYSTEMS
58
+ // ============================================================================
59
+
60
+ /**
61
+ * Template Manager - Extensible template system for React component generation
62
+ * Provides: multiple component patterns (functional, class, forwardRef, styled-components)
63
+ */
64
+ export { TemplateManager, templateManager } from './core/template-manager.js';
65
+
66
+ /**
67
+ * Framework Template Engine - Universal template generator supporting multiple UI frameworks
68
+ * Provides: React, Vue, Svelte, Angular, Solid, Preact, Lit, and Vanilla JS components
69
+ */
70
+ export {
71
+ FrameworkTemplateEngine,
72
+ frameworkTemplateEngine,
73
+ type FrameworkType,
74
+ type FrameworkOptions
75
+ } from './core/framework-templates.js';
76
+
77
+ // ============================================================================
78
+ // PLUGIN ARCHITECTURE
79
+ // ============================================================================
80
+
81
+ /**
82
+ * Plugin Manager - Extensible plugin system for SVG processing enhancements
83
+ * Provides: plugin registration, lifecycle management, and content processing pipeline
84
+ */
85
+ export { PluginManager, pluginManager } from './core/plugin-manager.js';
86
+
87
+ // ============================================================================
88
+ // UTILITY SERVICES
89
+ // ============================================================================
90
+
91
+ /**
92
+ * Native Node.js Utilities - Zero-dependency replacements for external libraries
93
+ * Provides: file operations, string manipulation, CLI parsing, and file watching
94
+ */
95
+ export {
96
+ toPascalCase,
97
+ FileSystem,
98
+ CLI,
99
+ FileWatcher
100
+ } from './utils/native.js';
101
+
102
+ /**
103
+ * File System Lock Functions - Concurrent file operation safety with advisory locking
104
+ * Provides: file locking, unlocking, and lock status checking for safe concurrent access
105
+ */
106
+ export { lockFiles, unlockFiles, isLocked } from './lock.js';
107
+
108
+ /**
109
+ * File System Watcher - Real-time file system monitoring with change detection
110
+ * Provides: directory watching, file change detection, and event-driven processing
111
+ */
112
+ export { watchSVGs } from './watch.js';
113
+
114
+ /**
115
+ * Project Builder - Automated project structure creation and dependency management
116
+ * Provides: project scaffolding, dependency resolution, and build automation
117
+ */
118
+ export { buildAll, generateSVG } from './builder.js';
119
+
120
+ /**
121
+ * Content Cleaner - SVG content optimization and sanitization utilities
122
+ * Provides: SVG cleaning, attribute normalization, and content optimization
123
+ */
124
+ export { clean } from './clean.js';
125
+
126
+ // ============================================================================
127
+ // TYPE DEFINITIONS
128
+ // ============================================================================
129
+
130
+ /**
131
+ * TypeScript Type Definitions - Comprehensive type system for all interfaces and configurations
132
+ * Provides: complete type safety for all operations, configurations, and data structures
133
+ */
134
+ export type {
135
+ // Core configuration types
136
+ SVGConfig,
137
+ ComponentGenerationOptions,
138
+
139
+ // Processing types
140
+ SVGProcessorResult,
141
+ ProcessingJob,
142
+ ProcessingStatus,
143
+
144
+ // Plugin system types
145
+ Plugin,
146
+ PluginConfig,
147
+
148
+ // Template system types
149
+ Template,
150
+ TemplateConfig,
151
+
152
+ // File operation types
153
+ WatchOptions
154
+ } from './types/index.js';
155
+
156
+ /**
157
+ * Error handling types - Available from core error handler
158
+ */
159
+ export type { SVGError, ErrorRecoveryStrategy } from './core/error-handler.js';
160
+
161
+ // ============================================================================
162
+ // TEMPLATES
163
+ // ============================================================================
164
+
165
+ /**
166
+ * Component Templates - Pre-built component templates for various use cases
167
+ * Provides: functional React component template with TypeScript support
168
+ */
169
+ export { reactTemplate } from './templates/ComponentTemplate.js';
170
+
171
+ // ============================================================================
172
+ // CONVENIENCE API
173
+ // ============================================================================
174
+
175
+ // Import instances for the convenience API
176
+ import { svgProcessor } from './processors/svg-processor.js';
177
+ import { watchSVGs } from './watch.js';
178
+ import { clean } from './clean.js';
179
+ import { buildAll } from './builder.js';
180
+
181
+ /**
182
+ * Quick Start API - Simplified API for common operations
183
+ * High-level functions for typical SVG processing workflows
184
+ */
185
+ export const SVGER = {
186
+ /**
187
+ * Process single SVG file to React component
188
+ */
189
+ processFile: svgProcessor.processSVGFile.bind(svgProcessor),
190
+
191
+ /**
192
+ * Process multiple SVG files in batch
193
+ */
194
+ processBatch: svgProcessor.processBatch.bind(svgProcessor),
195
+
196
+ /**
197
+ * Generate framework-agnostic component
198
+ */
199
+ generateFrameworkComponent: svgProcessor.generateFrameworkComponent.bind(svgProcessor),
200
+
201
+ /**
202
+ * Watch directory for changes
203
+ */
204
+ watch: watchSVGs,
205
+
206
+ /**
207
+ * Clean and optimize directory
208
+ */
209
+ clean,
210
+
211
+ /**
212
+ * Build all SVG files in directory
213
+ */
214
+ build: buildAll
215
+ } as const;
216
+
217
+ // ============================================================================
218
+ // VERSION INFORMATION
219
+ // ============================================================================
220
+
221
+ /**
222
+ * Package Version Information
223
+ */
224
+ export const VERSION = '2.0.0';
225
+ export const PACKAGE_NAME = 'svger-cli';
226
+
227
+ // ============================================================================
228
+ // DEFAULT EXPORT
229
+ // ============================================================================
230
+
231
+ /**
232
+ * Default export - Primary SVG processor instance for quick access
233
+ * Most common entry point for programmatic usage
234
+ */
235
+ export default svgProcessor;
package/src/lock.ts CHANGED
@@ -1,4 +1,4 @@
1
- import fs from "fs-extra";
1
+ import fs from "fs";
2
2
  import path from "path";
3
3
 
4
4
  const LOCK_FILE = ".svg-lock";
@@ -0,0 +1,288 @@
1
+ import path from 'path';
2
+ import { toPascalCase, FileSystem } from '../utils/native.js';
3
+ import { ComponentGenerationOptions, SVGProcessorResult, ProcessingJob, ProcessingStatus } from '../types/index.js';
4
+ import { logger } from '../core/logger.js';
5
+ import { pluginManager } from '../core/plugin-manager.js';
6
+ import { templateManager } from '../core/template-manager.js';
7
+ import { performanceEngine } from '../core/performance-engine.js';
8
+ import { frameworkTemplateEngine } from '../core/framework-templates.js';
9
+
10
+ /**
11
+ * SVG content processor and component generator
12
+ */
13
+ export class SVGProcessor {
14
+ private static instance: SVGProcessor;
15
+ private processingQueue: Map<string, ProcessingJob> = new Map();
16
+ private jobCounter = 0;
17
+
18
+ private constructor() {}
19
+
20
+ public static getInstance(): SVGProcessor {
21
+ if (!SVGProcessor.instance) {
22
+ SVGProcessor.instance = new SVGProcessor();
23
+ }
24
+ return SVGProcessor.instance;
25
+ }
26
+
27
+ /**
28
+ * Clean and optimize SVG content
29
+ */
30
+ public cleanSVGContent(svgContent: string): string {
31
+ logger.debug('Cleaning SVG content');
32
+
33
+ return svgContent
34
+ // Remove XML declaration
35
+ .replace(/<\?xml.*?\?>/g, '')
36
+ // Remove DOCTYPE declaration
37
+ .replace(/<!DOCTYPE.*?>/g, '')
38
+ // Remove comments
39
+ .replace(/<!--[\s\S]*?-->/g, '')
40
+ // Normalize whitespace
41
+ .replace(/\r?\n|\r/g, '')
42
+ .replace(/\s{2,}/g, ' ')
43
+ // Remove inline styles (they interfere with React styling)
44
+ .replace(/style="[^"]*"/g, '')
45
+ // Remove xmlns attributes (React will handle these)
46
+ .replace(/\s+xmlns(:xlink)?="[^"]*"/g, '')
47
+ // Convert attributes to camelCase for React
48
+ .replace(/fill-rule/g, 'fillRule')
49
+ .replace(/clip-rule/g, 'clipRule')
50
+ .replace(/stroke-width/g, 'strokeWidth')
51
+ .replace(/stroke-linecap/g, 'strokeLinecap')
52
+ .replace(/stroke-linejoin/g, 'strokeLinejoin')
53
+ .replace(/stroke-miterlimit/g, 'strokeMiterlimit')
54
+ .replace(/stroke-dasharray/g, 'strokeDasharray')
55
+ .replace(/stroke-dashoffset/g, 'strokeDashoffset')
56
+ .replace(/font-family/g, 'fontFamily')
57
+ .replace(/font-size/g, 'fontSize')
58
+ .replace(/font-weight/g, 'fontWeight')
59
+ .replace(/text-anchor/g, 'textAnchor')
60
+ // Remove outer SVG tag and keep inner content
61
+ .trim()
62
+ .replace(/^<svg[^>]*>([\s\S]*)<\/svg>$/i, '$1')
63
+ .trim();
64
+ }
65
+
66
+ /**
67
+ * Extract viewBox from SVG content
68
+ */
69
+ public extractViewBox(svgContent: string): string | null {
70
+ const viewBoxMatch = svgContent.match(/viewBox=["']([^"']+)["']/i);
71
+ return viewBoxMatch ? viewBoxMatch[1] : null;
72
+ }
73
+
74
+ /**
75
+ * Generate component name from filename
76
+ */
77
+ public generateComponentName(fileName: string): string {
78
+ const baseName = path.basename(fileName, '.svg');
79
+ const componentName = toPascalCase(baseName);
80
+
81
+ // Ensure component name starts with uppercase letter
82
+ if (!/^[A-Z]/.test(componentName)) {
83
+ return `Svg${componentName}`;
84
+ }
85
+
86
+ return componentName;
87
+ }
88
+
89
+ /**
90
+ * Generate React component from SVG content
91
+ */
92
+ public async generateComponent(
93
+ componentName: string,
94
+ svgContent: string,
95
+ options: Partial<ComponentGenerationOptions> = {}
96
+ ): Promise<string> {
97
+ try {
98
+ // Clean and optimize SVG content
99
+ const cleanedContent = this.cleanSVGContent(svgContent);
100
+
101
+ // Apply plugins (no plugin configs for now, just process directly)
102
+ const processedContent = cleanedContent;
103
+
104
+ // Create full options object with required fields
105
+ const fullOptions: ComponentGenerationOptions = {
106
+ componentName,
107
+ svgContent: processedContent,
108
+ framework: options.framework || 'react',
109
+ typescript: options.typescript !== undefined ? options.typescript : true,
110
+ ...options
111
+ };
112
+
113
+ // Use framework template engine directly
114
+ const component = frameworkTemplateEngine.generateComponent(fullOptions);
115
+
116
+ logger.debug(`Generated component: ${componentName}`);
117
+ return component;
118
+
119
+ } catch (error) {
120
+ logger.error(`Failed to generate component ${componentName}:`, error);
121
+ throw error;
122
+ }
123
+ }
124
+
125
+ /**
126
+ * Generate framework-agnostic component from SVG content
127
+ */
128
+ public async generateFrameworkComponent(
129
+ componentName: string,
130
+ svgContent: string,
131
+ options: ComponentGenerationOptions
132
+ ): Promise<string> {
133
+ try {
134
+ // Optimize SVG content based on framework requirements
135
+ const optimizationLevel = options.framework === 'vanilla' ? 'maximum' : 'balanced';
136
+ const optimizedContent = performanceEngine.optimizeSVGContent(svgContent, optimizationLevel);
137
+
138
+ // Generate framework-specific component
139
+ const component = frameworkTemplateEngine.generateComponent({
140
+ ...options,
141
+ componentName,
142
+ svgContent: optimizedContent
143
+ });
144
+
145
+ logger.debug(`Generated ${options.framework} component: ${componentName}`);
146
+ return component;
147
+
148
+ } catch (error) {
149
+ logger.error(`Failed to generate ${options.framework} component ${componentName}:`, error);
150
+ throw error;
151
+ }
152
+ }
153
+
154
+ /**
155
+ * Process multiple SVG files in batch with performance optimization
156
+ */
157
+ public async processBatch(
158
+ files: Array<{ path: string; outputDir: string; options?: Partial<ComponentGenerationOptions> }>,
159
+ config: { batchSize?: number; parallel?: boolean; maxConcurrency?: number } = {}
160
+ ): Promise<Array<{ success: boolean; filePath: string; error?: Error; duration: number }>> {
161
+ logger.info(`Starting batch processing of ${files.length} files`);
162
+
163
+ try {
164
+ const results = await performanceEngine.processBatch(files, config);
165
+
166
+ // Log performance metrics
167
+ const metrics = performanceEngine.getPerformanceMetrics();
168
+ if (metrics.memoryUsage.recommendations.length > 0) {
169
+ logger.warn('Performance recommendations:', metrics.memoryUsage.recommendations);
170
+ }
171
+
172
+ return results;
173
+ } catch (error) {
174
+ logger.error('Batch processing failed:', error);
175
+ throw error;
176
+ }
177
+ }
178
+
179
+ /**
180
+ * Process a single SVG file
181
+ */
182
+ public async processSVGFile(
183
+ svgFilePath: string,
184
+ outputDir: string,
185
+ options: Partial<ComponentGenerationOptions> = {}
186
+ ): Promise<SVGProcessorResult> {
187
+ const jobId = `job-${++this.jobCounter}`;
188
+ const job: ProcessingJob = {
189
+ id: jobId,
190
+ filePath: svgFilePath,
191
+ status: 'processing',
192
+ startTime: Date.now()
193
+ };
194
+
195
+ this.processingQueue.set(jobId, job);
196
+ logger.debug(`Processing SVG file: ${svgFilePath}`);
197
+
198
+ try {
199
+ // Read SVG content
200
+ const svgContent = await FileSystem.readFile(svgFilePath, 'utf-8');
201
+
202
+ // Generate component name
203
+ const componentName = this.generateComponentName(path.basename(svgFilePath));
204
+
205
+ // Generate component code
206
+ const componentCode = await this.generateComponent(
207
+ componentName,
208
+ svgContent,
209
+ options
210
+ );
211
+
212
+ // Ensure output directory exists
213
+ await FileSystem.ensureDir(outputDir);
214
+
215
+ // Get correct file extension based on framework
216
+ const framework = options.framework || 'react';
217
+ const typescript = options.typescript !== undefined ? options.typescript : true;
218
+ const fileExtension = frameworkTemplateEngine.getFileExtension(framework, typescript);
219
+
220
+ // Write component file
221
+ const outputFilePath = path.join(outputDir, `${componentName}.${fileExtension}`);
222
+ await FileSystem.writeFile(outputFilePath, componentCode, 'utf-8');
223
+
224
+ // Update job status
225
+ job.status = 'completed';
226
+ job.endTime = Date.now();
227
+
228
+ const result: SVGProcessorResult = {
229
+ success: true,
230
+ componentName,
231
+ filePath: outputFilePath
232
+ };
233
+
234
+ logger.success(`Generated component: ${componentName}.${fileExtension}`);
235
+ return result;
236
+
237
+ } catch (error) {
238
+ job.status = 'failed';
239
+ job.endTime = Date.now();
240
+ job.error = error as Error;
241
+
242
+ const result: SVGProcessorResult = {
243
+ success: false,
244
+ componentName: '',
245
+ filePath: svgFilePath,
246
+ error: error as Error
247
+ };
248
+
249
+ logger.error(`Failed to process ${svgFilePath}:`, error);
250
+ return result;
251
+ } finally {
252
+ // Clean up completed jobs after some time
253
+ setTimeout(() => {
254
+ this.processingQueue.delete(jobId);
255
+ }, 30000); // 30 seconds
256
+ }
257
+ }
258
+
259
+ /**
260
+ * Get processing statistics
261
+ */
262
+ public getProcessingStats(): {
263
+ total: number;
264
+ pending: number;
265
+ processing: number;
266
+ completed: number;
267
+ failed: number;
268
+ } {
269
+ const jobs = Array.from(this.processingQueue.values());
270
+ return {
271
+ total: jobs.length,
272
+ pending: jobs.filter(j => j.status === 'pending').length,
273
+ processing: jobs.filter(j => j.status === 'processing').length,
274
+ completed: jobs.filter(j => j.status === 'completed').length,
275
+ failed: jobs.filter(j => j.status === 'failed').length,
276
+ };
277
+ }
278
+
279
+ /**
280
+ * Clear processing queue
281
+ */
282
+ public clearQueue(): void {
283
+ this.processingQueue.clear();
284
+ }
285
+ }
286
+
287
+ // Export singleton instance
288
+ export const svgProcessor = SVGProcessor.getInstance();