svger-cli 2.0.2 → 2.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/dist/index.d.ts CHANGED
@@ -22,7 +22,7 @@ export { ConfigService, configService } from './services/config.js';
22
22
  * Error Handler - Comprehensive error management with recovery strategies
23
23
  * Provides: structured error handling, recovery mechanisms, and user-friendly messages
24
24
  */
25
- export { SVGErrorHandler, errorHandler, withErrorHandling, handleErrors } from './core/error-handler.js';
25
+ export { SVGErrorHandler, errorHandler, withErrorHandling, handleErrors, } from './core/error-handler.js';
26
26
  /**
27
27
  * SVG Processor - Core SVG content processing and React component generation
28
28
  * Provides: SVG parsing, optimization, React component generation, and batch processing
@@ -32,7 +32,7 @@ export { SVGProcessor, svgProcessor } from './processors/svg-processor.js';
32
32
  * Performance Engine - Advanced optimization for batch processing and parallel execution
33
33
  * Provides: batch processing, caching, memory optimization, and performance monitoring
34
34
  */
35
- export { PerformanceEngine, performanceEngine } from './core/performance-engine.js';
35
+ export { PerformanceEngine, performanceEngine, } from './core/performance-engine.js';
36
36
  /**
37
37
  * Style Compiler - Comprehensive styling system with responsive design and theming
38
38
  * Provides: CSS generation, theme management, responsive values, and style optimization
@@ -47,7 +47,7 @@ export { TemplateManager, templateManager } from './core/template-manager.js';
47
47
  * Framework Template Engine - Universal template generator supporting multiple UI frameworks
48
48
  * Provides: React, Vue, Svelte, Angular, Solid, Preact, Lit, and Vanilla JS components
49
49
  */
50
- export { FrameworkTemplateEngine, frameworkTemplateEngine, type FrameworkType, type FrameworkOptions } from './core/framework-templates.js';
50
+ export { FrameworkTemplateEngine, frameworkTemplateEngine, type FrameworkOptions, } from './core/framework-templates.js';
51
51
  /**
52
52
  * Plugin Manager - Extensible plugin system for SVG processing enhancements
53
53
  * Provides: plugin registration, lifecycle management, and content processing pipeline
@@ -57,7 +57,7 @@ export { PluginManager, pluginManager } from './core/plugin-manager.js';
57
57
  * Native Node.js Utilities - Zero-dependency replacements for external libraries
58
58
  * Provides: file operations, string manipulation, CLI parsing, and file watching
59
59
  */
60
- export { toPascalCase, FileSystem, CLI, FileWatcher } from './utils/native.js';
60
+ export { toPascalCase, toCamelCase, toKebabCase, FileSystem, CLI, FileWatcher, } from './utils/native.js';
61
61
  /**
62
62
  * File System Lock Functions - Concurrent file operation safety with advisory locking
63
63
  * Provides: file locking, unlocking, and lock status checking for safe concurrent access
@@ -82,7 +82,7 @@ export { clean } from './clean.js';
82
82
  * TypeScript Type Definitions - Comprehensive type system for all interfaces and configurations
83
83
  * Provides: complete type safety for all operations, configurations, and data structures
84
84
  */
85
- export type { SVGConfig, ComponentGenerationOptions, SVGProcessorResult, ProcessingJob, ProcessingStatus, Plugin, PluginConfig, Template, TemplateConfig, WatchOptions } from './types/index.js';
85
+ export type { SVGConfig, ComponentGenerationOptions, OutputConfig, NamingConvention, FrameworkType, SVGProcessorResult, ProcessingJob, ProcessingStatus, Plugin, PluginConfig, Template, TemplateConfig, WatchOptions, } from './types/index.js';
86
86
  /**
87
87
  * Error handling types - Available from core error handler
88
88
  */
@@ -104,7 +104,9 @@ export declare const SVGER: {
104
104
  /**
105
105
  * Process single SVG file to React component
106
106
  */
107
- readonly processFile: (svgFilePath: string, outputDir: string, options?: Partial<import("./types/index.js").ComponentGenerationOptions>) => Promise<import("./types/index.js").SVGProcessorResult>;
107
+ readonly processFile: (svgFilePath: string, outputDir: string, options?: Partial<import("./types/index.js").ComponentGenerationOptions & {
108
+ namingConvention?: import("./types/index.js").NamingConvention;
109
+ }>) => Promise<import("./types/index.js").SVGProcessorResult>;
108
110
  /**
109
111
  * Process multiple SVG files in batch
110
112
  */
package/dist/index.js CHANGED
@@ -25,7 +25,7 @@ export { ConfigService, configService } from './services/config.js';
25
25
  * Error Handler - Comprehensive error management with recovery strategies
26
26
  * Provides: structured error handling, recovery mechanisms, and user-friendly messages
27
27
  */
28
- export { SVGErrorHandler, errorHandler, withErrorHandling, handleErrors } from './core/error-handler.js';
28
+ export { SVGErrorHandler, errorHandler, withErrorHandling, handleErrors, } from './core/error-handler.js';
29
29
  // ============================================================================
30
30
  // PROCESSING ENGINES
31
31
  // ============================================================================
@@ -38,7 +38,7 @@ export { SVGProcessor, svgProcessor } from './processors/svg-processor.js';
38
38
  * Performance Engine - Advanced optimization for batch processing and parallel execution
39
39
  * Provides: batch processing, caching, memory optimization, and performance monitoring
40
40
  */
41
- export { PerformanceEngine, performanceEngine } from './core/performance-engine.js';
41
+ export { PerformanceEngine, performanceEngine, } from './core/performance-engine.js';
42
42
  /**
43
43
  * Style Compiler - Comprehensive styling system with responsive design and theming
44
44
  * Provides: CSS generation, theme management, responsive values, and style optimization
@@ -56,7 +56,7 @@ export { TemplateManager, templateManager } from './core/template-manager.js';
56
56
  * Framework Template Engine - Universal template generator supporting multiple UI frameworks
57
57
  * Provides: React, Vue, Svelte, Angular, Solid, Preact, Lit, and Vanilla JS components
58
58
  */
59
- export { FrameworkTemplateEngine, frameworkTemplateEngine } from './core/framework-templates.js';
59
+ export { FrameworkTemplateEngine, frameworkTemplateEngine, } from './core/framework-templates.js';
60
60
  // ============================================================================
61
61
  // PLUGIN ARCHITECTURE
62
62
  // ============================================================================
@@ -72,7 +72,7 @@ export { PluginManager, pluginManager } from './core/plugin-manager.js';
72
72
  * Native Node.js Utilities - Zero-dependency replacements for external libraries
73
73
  * Provides: file operations, string manipulation, CLI parsing, and file watching
74
74
  */
75
- export { toPascalCase, FileSystem, CLI, FileWatcher } from './utils/native.js';
75
+ export { toPascalCase, toCamelCase, toKebabCase, FileSystem, CLI, FileWatcher, } from './utils/native.js';
76
76
  /**
77
77
  * File System Lock Functions - Concurrent file operation safety with advisory locking
78
78
  * Provides: file locking, unlocking, and lock status checking for safe concurrent access
@@ -137,7 +137,7 @@ export const SVGER = {
137
137
  /**
138
138
  * Build all SVG files in directory
139
139
  */
140
- build: buildAll
140
+ build: buildAll,
141
141
  };
142
142
  // ============================================================================
143
143
  // VERSION INFORMATION
package/dist/lock.js CHANGED
@@ -1,6 +1,6 @@
1
- import fs from "fs";
2
- import path from "path";
3
- const LOCK_FILE = ".svg-lock";
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ const LOCK_FILE = '.svg-lock';
4
4
  /**
5
5
  * Get the absolute path to the lock file.
6
6
  *
@@ -18,7 +18,7 @@ function readLockFile() {
18
18
  if (!fs.existsSync(getLockFilePath()))
19
19
  return [];
20
20
  try {
21
- const data = fs.readFileSync(getLockFilePath(), "utf-8");
21
+ const data = fs.readFileSync(getLockFilePath(), 'utf-8');
22
22
  return JSON.parse(data);
23
23
  }
24
24
  catch (e) {
@@ -31,7 +31,7 @@ function readLockFile() {
31
31
  * @param {string[]} files - Array of SVG file names to lock.
32
32
  */
33
33
  function writeLockFile(files) {
34
- fs.writeFileSync(getLockFilePath(), JSON.stringify(files, null, 2), "utf-8");
34
+ fs.writeFileSync(getLockFilePath(), JSON.stringify(files, null, 2), 'utf-8');
35
35
  }
36
36
  /**
37
37
  * Lock one or more SVG files to prevent them from being processed.
@@ -43,7 +43,7 @@ export function lockFiles(files) {
43
43
  const current = readLockFile();
44
44
  const newFiles = Array.from(new Set([...current, ...fileNames]));
45
45
  writeLockFile(newFiles);
46
- console.log(`🔒 Locked files: ${newFiles.join(", ")}`);
46
+ console.log(`🔒 Locked files: ${newFiles.join(', ')}`);
47
47
  }
48
48
  /**
49
49
  * Unlock one or more SVG files, allowing them to be processed again.
@@ -55,7 +55,7 @@ export function unlockFiles(files) {
55
55
  const current = readLockFile();
56
56
  const remaining = current.filter(f => !fileNames.includes(f));
57
57
  writeLockFile(remaining);
58
- console.log(`🔓 Unlocked files: ${fileNames.join(", ")}`);
58
+ console.log(`🔓 Unlocked files: ${fileNames.join(', ')}`);
59
59
  }
60
60
  /**
61
61
  * Check if a specific SVG file is locked.
@@ -1,4 +1,4 @@
1
- import { ComponentGenerationOptions, SVGProcessorResult } from '../types/index.js';
1
+ import { ComponentGenerationOptions, SVGProcessorResult, NamingConvention } from '../types/index.js';
2
2
  /**
3
3
  * SVG content processor and component generator
4
4
  */
@@ -19,7 +19,7 @@ export declare class SVGProcessor {
19
19
  /**
20
20
  * Generate component name from filename
21
21
  */
22
- generateComponentName(fileName: string): string;
22
+ generateComponentName(fileName: string, namingConvention?: 'kebab' | 'pascal' | 'camel'): string;
23
23
  /**
24
24
  * Generate React component from SVG content
25
25
  */
@@ -45,10 +45,16 @@ export declare class SVGProcessor {
45
45
  error?: Error;
46
46
  duration: number;
47
47
  }>>;
48
+ /**
49
+ * Generate filename from component name using naming convention
50
+ */
51
+ generateFileName(componentName: string, extension: string, namingConvention?: NamingConvention): string;
48
52
  /**
49
53
  * Process a single SVG file
50
54
  */
51
- processSVGFile(svgFilePath: string, outputDir: string, options?: Partial<ComponentGenerationOptions>): Promise<SVGProcessorResult>;
55
+ processSVGFile(svgFilePath: string, outputDir: string, options?: Partial<ComponentGenerationOptions & {
56
+ namingConvention?: NamingConvention;
57
+ }>): Promise<SVGProcessorResult>;
52
58
  /**
53
59
  * Get processing statistics
54
60
  */
@@ -1,5 +1,5 @@
1
1
  import path from 'path';
2
- import { toPascalCase, FileSystem } from '../utils/native.js';
2
+ import { toPascalCase, toKebabCase, toCamelCase, FileSystem, } from '../utils/native.js';
3
3
  import { logger } from '../core/logger.js';
4
4
  import { performanceEngine } from '../core/performance-engine.js';
5
5
  import { frameworkTemplateEngine } from '../core/framework-templates.js';
@@ -22,7 +22,7 @@ export class SVGProcessor {
22
22
  */
23
23
  cleanSVGContent(svgContent) {
24
24
  logger.debug('Cleaning SVG content');
25
- return svgContent
25
+ return (svgContent
26
26
  // Remove XML declaration
27
27
  .replace(/<\?xml.*?\?>/g, '')
28
28
  // Remove DOCTYPE declaration
@@ -52,7 +52,7 @@ export class SVGProcessor {
52
52
  // Remove outer SVG tag and keep inner content
53
53
  .trim()
54
54
  .replace(/^<svg[^>]*>([\s\S]*)<\/svg>$/i, '$1')
55
- .trim();
55
+ .trim());
56
56
  }
57
57
  /**
58
58
  * Extract viewBox from SVG content
@@ -64,14 +64,27 @@ export class SVGProcessor {
64
64
  /**
65
65
  * Generate component name from filename
66
66
  */
67
- generateComponentName(fileName) {
67
+ generateComponentName(fileName, namingConvention) {
68
68
  const baseName = path.basename(fileName, '.svg');
69
- const componentName = toPascalCase(baseName);
70
- // Ensure component name starts with uppercase letter
71
- if (!/^[A-Z]/.test(componentName)) {
72
- return `Svg${componentName}`;
69
+ // Apply naming convention if specified, otherwise default to PascalCase
70
+ switch (namingConvention) {
71
+ case 'kebab':
72
+ // Keep kebab-case for filename, but component still needs PascalCase
73
+ return toPascalCase(baseName);
74
+ case 'camel':
75
+ // Convert to camelCase
76
+ const pascalName = toPascalCase(baseName);
77
+ return pascalName.charAt(0).toLowerCase() + pascalName.slice(1);
78
+ case 'pascal':
79
+ default:
80
+ // Default to PascalCase
81
+ const componentName = toPascalCase(baseName);
82
+ // Ensure component name starts with uppercase letter
83
+ if (!/^[A-Z]/.test(componentName)) {
84
+ return `Svg${componentName}`;
85
+ }
86
+ return componentName;
73
87
  }
74
- return componentName;
75
88
  }
76
89
  /**
77
90
  * Generate React component from SVG content
@@ -88,7 +101,7 @@ export class SVGProcessor {
88
101
  svgContent: processedContent,
89
102
  framework: options.framework || 'react',
90
103
  typescript: options.typescript !== undefined ? options.typescript : true,
91
- ...options
104
+ ...options,
92
105
  };
93
106
  // Use framework template engine directly
94
107
  const component = frameworkTemplateEngine.generateComponent(fullOptions);
@@ -112,7 +125,7 @@ export class SVGProcessor {
112
125
  const component = frameworkTemplateEngine.generateComponent({
113
126
  ...options,
114
127
  componentName,
115
- svgContent: optimizedContent
128
+ svgContent: optimizedContent,
116
129
  });
117
130
  logger.debug(`Generated ${options.framework} component: ${componentName}`);
118
131
  return component;
@@ -141,6 +154,26 @@ export class SVGProcessor {
141
154
  throw error;
142
155
  }
143
156
  }
157
+ /**
158
+ * Generate filename from component name using naming convention
159
+ */
160
+ generateFileName(componentName, extension, namingConvention) {
161
+ let fileName;
162
+ switch (namingConvention) {
163
+ case 'kebab':
164
+ fileName = toKebabCase(componentName);
165
+ break;
166
+ case 'camel':
167
+ fileName = toCamelCase(componentName);
168
+ break;
169
+ case 'pascal':
170
+ default:
171
+ // Default to PascalCase (same as component name)
172
+ fileName = componentName;
173
+ break;
174
+ }
175
+ return `${fileName}.${extension}`;
176
+ }
144
177
  /**
145
178
  * Process a single SVG file
146
179
  */
@@ -150,14 +183,14 @@ export class SVGProcessor {
150
183
  id: jobId,
151
184
  filePath: svgFilePath,
152
185
  status: 'processing',
153
- startTime: Date.now()
186
+ startTime: Date.now(),
154
187
  };
155
188
  this.processingQueue.set(jobId, job);
156
189
  logger.debug(`Processing SVG file: ${svgFilePath}`);
157
190
  try {
158
191
  // Read SVG content
159
192
  const svgContent = await FileSystem.readFile(svgFilePath, 'utf-8');
160
- // Generate component name
193
+ // Generate component name (always PascalCase for component)
161
194
  const componentName = this.generateComponentName(path.basename(svgFilePath));
162
195
  // Generate component code
163
196
  const componentCode = await this.generateComponent(componentName, svgContent, options);
@@ -167,8 +200,11 @@ export class SVGProcessor {
167
200
  const framework = options.framework || 'react';
168
201
  const typescript = options.typescript !== undefined ? options.typescript : true;
169
202
  const fileExtension = frameworkTemplateEngine.getFileExtension(framework, typescript);
203
+ // Generate filename using naming convention
204
+ const namingConvention = options.namingConvention;
205
+ const fileName = this.generateFileName(componentName, fileExtension, namingConvention);
170
206
  // Write component file
171
- const outputFilePath = path.join(outputDir, `${componentName}.${fileExtension}`);
207
+ const outputFilePath = path.join(outputDir, fileName);
172
208
  await FileSystem.writeFile(outputFilePath, componentCode, 'utf-8');
173
209
  // Update job status
174
210
  job.status = 'completed';
@@ -176,9 +212,9 @@ export class SVGProcessor {
176
212
  const result = {
177
213
  success: true,
178
214
  componentName,
179
- filePath: outputFilePath
215
+ filePath: outputFilePath,
180
216
  };
181
- logger.success(`Generated component: ${componentName}.${fileExtension}`);
217
+ logger.success(`Generated component: ${fileName}`);
182
218
  return result;
183
219
  }
184
220
  catch (error) {
@@ -189,7 +225,7 @@ export class SVGProcessor {
189
225
  success: false,
190
226
  componentName: '',
191
227
  filePath: svgFilePath,
192
- error: error
228
+ error: error,
193
229
  };
194
230
  logger.error(`Failed to process ${svgFilePath}:`, error);
195
231
  return result;
@@ -35,25 +35,25 @@ export class ConfigService {
35
35
  },
36
36
  plugins: [],
37
37
  template: {
38
- type: 'default'
38
+ type: 'default',
39
39
  },
40
40
  frameworkOptions: {
41
41
  forwardRef: true,
42
42
  memo: false,
43
43
  scriptSetup: true,
44
- standalone: true
44
+ standalone: true,
45
45
  },
46
46
  errorHandling: {
47
47
  skipOnError: false,
48
48
  logLevel: 'info',
49
- maxRetries: 3
49
+ maxRetries: 3,
50
50
  },
51
51
  performance: {
52
52
  batchSize: 10,
53
53
  parallel: true,
54
54
  timeout: 30000,
55
- enableCache: true
56
- }
55
+ enableCache: true,
56
+ },
57
57
  };
58
58
  }
59
59
  /**
@@ -79,7 +79,7 @@ export class ConfigService {
79
79
  // Merge with defaults to ensure all required properties exist
80
80
  this.cachedConfig = {
81
81
  ...this.getDefaultConfig(),
82
- ...configData
82
+ ...configData,
83
83
  };
84
84
  logger.debug('Configuration loaded successfully');
85
85
  return this.cachedConfig;
@@ -165,7 +165,8 @@ export class ConfigService {
165
165
  // Required string fields
166
166
  const requiredStringFields = ['source', 'output', 'defaultFill'];
167
167
  for (const field of requiredStringFields) {
168
- if (!configToValidate[field] || typeof configToValidate[field] !== 'string') {
168
+ if (!configToValidate[field] ||
169
+ typeof configToValidate[field] !== 'string') {
169
170
  errors.push(`${field} must be a non-empty string`);
170
171
  }
171
172
  }
@@ -182,12 +183,13 @@ export class ConfigService {
182
183
  errors.push('exclude must be an array');
183
184
  }
184
185
  // Validate styleRules object
185
- if (configToValidate.styleRules && typeof configToValidate.styleRules !== 'object') {
186
+ if (configToValidate.styleRules &&
187
+ typeof configToValidate.styleRules !== 'object') {
186
188
  errors.push('styleRules must be an object');
187
189
  }
188
190
  return {
189
191
  valid: errors.length === 0,
190
- errors
192
+ errors,
191
193
  };
192
194
  }
193
195
  /**
@@ -30,7 +30,7 @@ export class FileWatcherService {
30
30
  try {
31
31
  const watcher = fs.watch(resolvedPath, {
32
32
  persistent: true,
33
- recursive: false
33
+ recursive: false,
34
34
  }, (eventType, filename) => {
35
35
  if (filename) {
36
36
  this.handleFileEvent(watchId, eventType, path.join(resolvedPath, filename));
@@ -83,7 +83,7 @@ export class FileWatcherService {
83
83
  const event = {
84
84
  type: actualEventType,
85
85
  filePath,
86
- timestamp: Date.now()
86
+ timestamp: Date.now(),
87
87
  };
88
88
  logger.debug(`File event: ${actualEventType} - ${path.basename(filePath)}`);
89
89
  // Emit event to registered handlers
@@ -160,7 +160,7 @@ export class FileWatcherService {
160
160
  return {
161
161
  activeWatchers: this.watchers.size,
162
162
  pendingEvents: this.debounceTimers.size,
163
- totalHandlers
163
+ totalHandlers,
164
164
  };
165
165
  }
166
166
  /**
@@ -41,9 +41,15 @@ export class SVGService {
41
41
  ...config,
42
42
  ...(options.config || {}),
43
43
  // Support direct properties on options for CLI convenience
44
- ...options.framework && { framework: options.framework },
45
- ...options.typescript !== undefined && { typescript: options.typescript },
46
- ...options.frameworkOptions && { frameworkOptions: options.frameworkOptions }
44
+ ...(options.framework && {
45
+ framework: options.framework,
46
+ }),
47
+ ...(options.typescript !== undefined && {
48
+ typescript: options.typescript,
49
+ }),
50
+ ...(options.frameworkOptions && {
51
+ frameworkOptions: options.frameworkOptions,
52
+ }),
47
53
  };
48
54
  // Read all SVG files
49
55
  const files = await FileSystem.readDir(srcDir);
@@ -70,12 +76,12 @@ export class SVGService {
70
76
  defaultWidth: mergedConfig.defaultWidth,
71
77
  defaultHeight: mergedConfig.defaultHeight,
72
78
  defaultFill: mergedConfig.defaultFill,
73
- styleRules: Object.fromEntries(Object.entries(mergedConfig.styleRules || {}).filter(([_, v]) => v !== undefined))
79
+ styleRules: Object.fromEntries(Object.entries(mergedConfig.styleRules || {}).filter(([_, v]) => v !== undefined)),
74
80
  });
75
81
  results.push({
76
82
  success: processingResult.success,
77
83
  file,
78
- error: processingResult.error
84
+ error: processingResult.error,
79
85
  });
80
86
  }
81
87
  catch (error) {
@@ -83,7 +89,7 @@ export class SVGService {
83
89
  results.push({
84
90
  success: false,
85
91
  file,
86
- error: error
92
+ error: error,
87
93
  });
88
94
  }
89
95
  }
@@ -93,7 +99,9 @@ export class SVGService {
93
99
  logger.info(`Build complete: ${successful} successful, ${failed} failed`);
94
100
  if (failed > 0) {
95
101
  logger.warn('Some files failed to process:');
96
- results.filter(r => !r.success).forEach(r => {
102
+ results
103
+ .filter(r => !r.success)
104
+ .forEach(r => {
97
105
  logger.warn(` - ${r.file}: ${r.error?.message}`);
98
106
  });
99
107
  }
@@ -126,7 +134,7 @@ export class SVGService {
126
134
  defaultWidth: mergedConfig.defaultWidth,
127
135
  defaultHeight: mergedConfig.defaultHeight,
128
136
  defaultFill: mergedConfig.defaultFill,
129
- styleRules: Object.fromEntries(Object.entries(mergedConfig.styleRules || {}).filter(([_, v]) => v !== undefined))
137
+ styleRules: Object.fromEntries(Object.entries(mergedConfig.styleRules || {}).filter(([_, v]) => v !== undefined)),
130
138
  });
131
139
  if (!result.success) {
132
140
  throw result.error || new Error('Failed to generate component');
@@ -194,7 +202,7 @@ export class SVGService {
194
202
  defaultWidth: mergedConfig.defaultWidth,
195
203
  defaultHeight: mergedConfig.defaultHeight,
196
204
  defaultFill: mergedConfig.defaultFill,
197
- styleRules: Object.fromEntries(Object.entries(mergedConfig.styleRules || {}).filter(([_, v]) => v !== undefined))
205
+ styleRules: Object.fromEntries(Object.entries(mergedConfig.styleRules || {}).filter(([_, v]) => v !== undefined)),
198
206
  });
199
207
  }
200
208
  catch (error) {
@@ -267,7 +275,9 @@ export class SVGService {
267
275
  * Generate the content for index.ts file
268
276
  */
269
277
  generateIndexContent(componentNames) {
270
- const imports = componentNames.map(name => `export { default as ${name} } from './${name}';`).join('\n');
278
+ const imports = componentNames
279
+ .map(name => `export { default as ${name} } from './${name}';`)
280
+ .join('\n');
271
281
  const exportAll = `
272
282
  // Export all components
273
283
  export {
@@ -300,7 +310,7 @@ ${imports}${exportAll}`;
300
310
  return {
301
311
  activeWatchers: this.activeWatchers.size,
302
312
  processingQueue: svgProcessor.getProcessingStats(),
303
- watcherStats: fileWatcher.getWatchStats()
313
+ watcherStats: fileWatcher.getWatchStats(),
304
314
  };
305
315
  }
306
316
  /**
@@ -346,7 +356,9 @@ export class LockService {
346
356
  }
347
357
  writeLockFile(locks) {
348
358
  try {
349
- FileSystem.writeJSONSync(this.getLockFilePath(), Array.from(locks), { spaces: 2 });
359
+ FileSystem.writeJSONSync(this.getLockFilePath(), Array.from(locks), {
360
+ spaces: 2,
361
+ });
350
362
  this.cachedLocks = locks;
351
363
  }
352
364
  catch (error) {
@@ -13,32 +13,32 @@
13
13
  * @param [options.defaultFill="currentColor"] - The default fill color for the SVG.
14
14
  * @returns A string containing the complete TypeScript code for the React SVG component.
15
15
  */
16
- export function reactTemplate({ componentName, svgContent, defaultWidth = 24, defaultHeight = 24, defaultFill = "currentColor", }) {
16
+ export function reactTemplate({ componentName, svgContent, defaultWidth = 24, defaultHeight = 24, defaultFill = 'currentColor', }) {
17
17
  const cleaned = svgContent
18
- .replace(/<\?xml.*?\?>/g, "")
19
- .replace(/<!DOCTYPE.*?>/g, "")
20
- .replace(/\r?\n|\r/g, "")
21
- .replace(/\s{2,}/g, " ")
22
- .replace(/style="[^"]*"/g, "")
23
- .replace(/\s+xmlns(:xlink)?="[^"]*"/g, "")
18
+ .replace(/<\?xml.*?\?>/g, '')
19
+ .replace(/<!DOCTYPE.*?>/g, '')
20
+ .replace(/\r?\n|\r/g, '')
21
+ .replace(/\s{2,}/g, ' ')
22
+ .replace(/style="[^"]*"/g, '')
23
+ .replace(/\s+xmlns(:xlink)?="[^"]*"/g, '')
24
24
  .trim()
25
- .replace(/^.*?<svg[^>]*>(.*?)<\/svg>.*$/i, "$1");
26
- return `import type { SVGProps } from "react";
27
- const Svg${componentName} = (props: SVGProps<SVGSVGElement>) => (
28
- <svg
29
- viewBox="0 0 ${defaultWidth} ${defaultHeight}"
30
- xmlns="http://www.w3.org/2000/svg"
31
- xmlnsXlink="http://www.w3.org/1999/xlink"
32
- width={props.width || ${defaultWidth}}
33
- height={props.height || ${defaultHeight}}
34
- fill={props.fill || "${defaultFill}"}
35
- stroke={props.stroke || "none"}
36
- className={props.className}
37
- {...props}
38
- >
39
- ${cleaned}
40
- </svg>
41
- );
42
- export default Svg${componentName};
25
+ .replace(/^.*?<svg[^>]*>(.*?)<\/svg>.*$/i, '$1');
26
+ return `import type { SVGProps } from "react";
27
+ const Svg${componentName} = (props: SVGProps<SVGSVGElement>) => (
28
+ <svg
29
+ viewBox="0 0 ${defaultWidth} ${defaultHeight}"
30
+ xmlns="http://www.w3.org/2000/svg"
31
+ xmlnsXlink="http://www.w3.org/1999/xlink"
32
+ width={props.width || ${defaultWidth}}
33
+ height={props.height || ${defaultHeight}}
34
+ fill={props.fill || "${defaultFill}"}
35
+ stroke={props.stroke || "none"}
36
+ className={props.className}
37
+ {...props}
38
+ >
39
+ ${cleaned}
40
+ </svg>
41
+ );
42
+ export default Svg${componentName};
43
43
  `;
44
44
  }
@@ -2,9 +2,15 @@
2
2
  * Type definitions for svger-cli
3
3
  */
4
4
  export type FrameworkType = 'react' | 'vue' | 'svelte' | 'angular' | 'solid' | 'preact' | 'lit' | 'vanilla';
5
+ export type NamingConvention = 'kebab' | 'pascal' | 'camel';
6
+ export interface OutputConfig {
7
+ naming?: NamingConvention;
8
+ extension?: string;
9
+ directory?: string;
10
+ }
5
11
  export interface SVGConfig {
6
12
  source: string;
7
- output: string;
13
+ output: string | OutputConfig;
8
14
  watch: boolean;
9
15
  framework: FrameworkType;
10
16
  typescript: boolean;
@@ -2,9 +2,39 @@
2
2
  * Native Node.js utilities to replace external dependencies
3
3
  */
4
4
  /**
5
- * Convert string to PascalCase (replaces change-case package)
5
+ * Convert a string to PascalCase.
6
+ * Handles kebab-case, snake_case, and space-separated strings.
7
+ *
8
+ * @param {string} str - Input string to convert.
9
+ * @returns {string} PascalCase string.
10
+ *
11
+ * @example
12
+ * toPascalCase('hello-world') => 'HelloWorld'
13
+ * toPascalCase('hello_world') => 'HelloWorld'
14
+ * toPascalCase('hello world') => 'HelloWorld'
6
15
  */
7
16
  export declare function toPascalCase(str: string): string;
17
+ /**
18
+ * Convert a string to camelCase.
19
+ *
20
+ * @param {string} str - Input string to convert.
21
+ * @returns {string} camelCase string.
22
+ *
23
+ * @example
24
+ * toCamelCase('hello-world') => 'helloWorld'
25
+ */
26
+ export declare function toCamelCase(str: string): string;
27
+ /**
28
+ * Convert a string to kebab-case.
29
+ *
30
+ * @param {string} str - Input string to convert.
31
+ * @returns {string} kebab-case string.
32
+ *
33
+ * @example
34
+ * toKebabCase('HelloWorld') => 'hello-world'
35
+ * toKebabCase('hello_world') => 'hello-world'
36
+ */
37
+ export declare function toKebabCase(str: string): string;
8
38
  /**
9
39
  * Native file system utilities (replaces fs-extra package)
10
40
  */