svger-cli 2.0.1 → 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.
Files changed (91) hide show
  1. package/.svgerconfig.example.json +38 -0
  2. package/CHANGELOG.md +64 -0
  3. package/DEVELOPMENT.md +353 -0
  4. package/README.md +24 -5
  5. package/SECURITY.md +69 -0
  6. package/dist/builder.js +16 -16
  7. package/dist/clean.js +2 -2
  8. package/dist/cli.js +38 -38
  9. package/dist/config.js +11 -11
  10. package/dist/core/error-handler.d.ts +63 -0
  11. package/dist/core/error-handler.js +227 -0
  12. package/dist/core/framework-templates.d.ts +17 -0
  13. package/{src/core/framework-templates.ts → dist/core/framework-templates.js} +104 -139
  14. package/dist/core/logger.d.ts +22 -0
  15. package/dist/core/logger.js +85 -0
  16. package/dist/core/performance-engine.d.ts +67 -0
  17. package/dist/core/performance-engine.js +252 -0
  18. package/dist/core/plugin-manager.d.ts +56 -0
  19. package/dist/core/plugin-manager.js +191 -0
  20. package/dist/core/style-compiler.d.ts +88 -0
  21. package/dist/core/style-compiler.js +468 -0
  22. package/dist/core/template-manager.d.ts +64 -0
  23. package/{src/core/template-manager.ts → dist/core/template-manager.js} +172 -255
  24. package/dist/index.d.ts +153 -0
  25. package/{src/index.ts → dist/index.js} +32 -110
  26. package/dist/lock.js +7 -7
  27. package/dist/processors/svg-processor.d.ts +73 -0
  28. package/dist/processors/svg-processor.js +261 -0
  29. package/dist/services/config.d.ts +55 -0
  30. package/dist/services/config.js +211 -0
  31. package/dist/services/file-watcher.d.ts +54 -0
  32. package/dist/services/file-watcher.js +180 -0
  33. package/dist/services/svg-service.d.ts +81 -0
  34. package/dist/services/svg-service.js +395 -0
  35. package/dist/templates/ComponentTemplate.js +25 -25
  36. package/dist/types/index.d.ts +146 -0
  37. package/dist/types/index.js +4 -0
  38. package/dist/utils/native.d.ts +104 -0
  39. package/dist/utils/native.js +340 -0
  40. package/dist/watch.d.ts +1 -1
  41. package/dist/watch.js +14 -14
  42. package/package.json +154 -14
  43. package/.svgconfig.json +0 -3
  44. package/CODE_OF_CONDUCT.md +0 -79
  45. package/CONTRIBUTING.md +0 -146
  46. package/TESTING.md +0 -143
  47. package/cli-framework.test.js +0 -16
  48. package/cli-test-angular/Arrowbenddownleft.component.ts +0 -27
  49. package/cli-test-angular/Vite.component.ts +0 -27
  50. package/cli-test-angular/index.ts +0 -25
  51. package/cli-test-output/Arrowbenddownleft.vue +0 -33
  52. package/cli-test-output/Vite.vue +0 -33
  53. package/cli-test-output/index.ts +0 -25
  54. package/cli-test-react/Arrowbenddownleft.tsx +0 -39
  55. package/cli-test-react/Vite.tsx +0 -39
  56. package/cli-test-react/index.ts +0 -25
  57. package/cli-test-svelte/Arrowbenddownleft.svelte +0 -22
  58. package/cli-test-svelte/Vite.svelte +0 -22
  59. package/cli-test-svelte/index.ts +0 -25
  60. package/frameworks.test.js +0 -170
  61. package/my-svgs/ArrowBendDownLeft.svg +0 -6
  62. package/my-svgs/vite.svg +0 -1
  63. package/src/builder.ts +0 -104
  64. package/src/clean.ts +0 -21
  65. package/src/cli.ts +0 -221
  66. package/src/config.ts +0 -81
  67. package/src/core/error-handler.ts +0 -303
  68. package/src/core/logger.ts +0 -104
  69. package/src/core/performance-engine.ts +0 -327
  70. package/src/core/plugin-manager.ts +0 -228
  71. package/src/core/style-compiler.ts +0 -605
  72. package/src/lock.ts +0 -74
  73. package/src/processors/svg-processor.ts +0 -288
  74. package/src/services/config.ts +0 -241
  75. package/src/services/file-watcher.ts +0 -218
  76. package/src/services/svg-service.ts +0 -468
  77. package/src/templates/ComponentTemplate.ts +0 -57
  78. package/src/types/index.ts +0 -169
  79. package/src/utils/native.ts +0 -352
  80. package/src/watch.ts +0 -88
  81. package/test-output-mulit/TestIcon-angular-module.component.ts +0 -26
  82. package/test-output-mulit/TestIcon-angular-standalone.component.ts +0 -27
  83. package/test-output-mulit/TestIcon-lit.ts +0 -35
  84. package/test-output-mulit/TestIcon-preact.tsx +0 -38
  85. package/test-output-mulit/TestIcon-react.tsx +0 -35
  86. package/test-output-mulit/TestIcon-solid.tsx +0 -27
  87. package/test-output-mulit/TestIcon-svelte.svelte +0 -22
  88. package/test-output-mulit/TestIcon-vanilla.ts +0 -37
  89. package/test-output-mulit/TestIcon-vue-composition.vue +0 -33
  90. package/test-output-mulit/TestIcon-vue-options.vue +0 -31
  91. package/tsconfig.json +0 -18
@@ -0,0 +1,395 @@
1
+ import path from 'path';
2
+ import { FileSystem } from '../utils/native.js';
3
+ import { logger } from '../core/logger.js';
4
+ import { configService } from './config.js';
5
+ import { svgProcessor } from '../processors/svg-processor.js';
6
+ import { fileWatcher } from './file-watcher.js';
7
+ /**
8
+ * Main SVG service that orchestrates all SVG processing operations
9
+ */
10
+ export class SVGService {
11
+ static instance;
12
+ activeWatchers = new Set();
13
+ lockService;
14
+ constructor() {
15
+ this.lockService = LockService.getInstance();
16
+ }
17
+ static getInstance() {
18
+ if (!SVGService.instance) {
19
+ SVGService.instance = new SVGService();
20
+ }
21
+ return SVGService.instance;
22
+ }
23
+ /**
24
+ * Build all SVG files from source to output directory
25
+ */
26
+ async buildAll(options) {
27
+ logger.info('Starting SVG build process');
28
+ logger.info(`Source: ${options.src}`);
29
+ logger.info(`Output: ${options.out}`);
30
+ const srcDir = path.resolve(options.src);
31
+ const outDir = path.resolve(options.out);
32
+ // Validate source directory
33
+ if (!(await FileSystem.exists(srcDir))) {
34
+ throw new Error(`Source folder not found: ${srcDir}`);
35
+ }
36
+ // Ensure output directory exists
37
+ await FileSystem.ensureDir(outDir);
38
+ // Get configuration - merge config file with options
39
+ const config = configService.readConfig();
40
+ const mergedConfig = {
41
+ ...config,
42
+ ...(options.config || {}),
43
+ // Support direct properties on options for CLI convenience
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
+ }),
53
+ };
54
+ // Read all SVG files
55
+ const files = await FileSystem.readDir(srcDir);
56
+ const svgFiles = files.filter((file) => file.endsWith('.svg'));
57
+ if (svgFiles.length === 0) {
58
+ logger.warn('No SVG files found in source directory');
59
+ return;
60
+ }
61
+ logger.info(`Found ${svgFiles.length} SVG files to process`);
62
+ const results = [];
63
+ // Process each SVG file
64
+ for (const file of svgFiles) {
65
+ const svgPath = path.join(srcDir, file);
66
+ // Check if file is locked
67
+ if (this.lockService.isLocked(svgPath)) {
68
+ logger.warn(`Skipped locked file: ${file}`);
69
+ continue;
70
+ }
71
+ try {
72
+ const processingResult = await svgProcessor.processSVGFile(svgPath, outDir, {
73
+ framework: mergedConfig.framework,
74
+ typescript: mergedConfig.typescript,
75
+ frameworkOptions: mergedConfig.frameworkOptions,
76
+ defaultWidth: mergedConfig.defaultWidth,
77
+ defaultHeight: mergedConfig.defaultHeight,
78
+ defaultFill: mergedConfig.defaultFill,
79
+ styleRules: Object.fromEntries(Object.entries(mergedConfig.styleRules || {}).filter(([_, v]) => v !== undefined)),
80
+ });
81
+ results.push({
82
+ success: processingResult.success,
83
+ file,
84
+ error: processingResult.error,
85
+ });
86
+ }
87
+ catch (error) {
88
+ logger.error(`Failed to process ${file}:`, error);
89
+ results.push({
90
+ success: false,
91
+ file,
92
+ error: error,
93
+ });
94
+ }
95
+ }
96
+ // Log summary
97
+ const successful = results.filter(r => r.success).length;
98
+ const failed = results.filter(r => !r.success).length;
99
+ logger.info(`Build complete: ${successful} successful, ${failed} failed`);
100
+ if (failed > 0) {
101
+ logger.warn('Some files failed to process:');
102
+ results
103
+ .filter(r => !r.success)
104
+ .forEach(r => {
105
+ logger.warn(` - ${r.file}: ${r.error?.message}`);
106
+ });
107
+ }
108
+ // Generate index.ts file with all component exports
109
+ if (successful > 0) {
110
+ await this.generateIndexFile(outDir, results.filter(r => r.success).map(r => r.file));
111
+ }
112
+ }
113
+ /**
114
+ * Generate a React component from a single SVG file
115
+ */
116
+ async generateSingle(options) {
117
+ logger.info(`Generating component from: ${options.svgFile}`);
118
+ const filePath = path.resolve(options.svgFile);
119
+ const outDir = path.resolve(options.outDir);
120
+ // Validate SVG file
121
+ if (!(await FileSystem.exists(filePath))) {
122
+ throw new Error(`SVG file not found: ${filePath}`);
123
+ }
124
+ // Check if file is locked
125
+ if (this.lockService.isLocked(filePath)) {
126
+ logger.warn(`File is locked: ${path.basename(options.svgFile)}`);
127
+ return;
128
+ }
129
+ // Get configuration
130
+ const config = configService.readConfig();
131
+ const mergedConfig = { ...config, ...options.config };
132
+ // Process the file
133
+ const result = await svgProcessor.processSVGFile(filePath, outDir, {
134
+ defaultWidth: mergedConfig.defaultWidth,
135
+ defaultHeight: mergedConfig.defaultHeight,
136
+ defaultFill: mergedConfig.defaultFill,
137
+ styleRules: Object.fromEntries(Object.entries(mergedConfig.styleRules || {}).filter(([_, v]) => v !== undefined)),
138
+ });
139
+ if (!result.success) {
140
+ throw result.error || new Error('Failed to generate component');
141
+ }
142
+ logger.success(`Component generated: ${result.componentName}`);
143
+ }
144
+ /**
145
+ * Start watching SVG files for changes
146
+ */
147
+ async startWatching(options) {
148
+ logger.info('Starting watch mode');
149
+ logger.info(`Watching: ${options.src}`);
150
+ logger.info(`Output: ${options.out}`);
151
+ const srcDir = path.resolve(options.src);
152
+ const outDir = path.resolve(options.out);
153
+ // Validate source directory
154
+ if (!(await FileSystem.exists(srcDir))) {
155
+ throw new Error(`Source folder not found: ${srcDir}`);
156
+ }
157
+ // Start watching
158
+ const watchId = await fileWatcher.watchDirectory(srcDir, options);
159
+ this.activeWatchers.add(watchId);
160
+ // Register event handler
161
+ fileWatcher.onFileEvent(watchId, async (event) => {
162
+ await this.handleWatchEvent(event, outDir, options.config);
163
+ });
164
+ logger.success(`Watch mode active - waiting for file changes...`);
165
+ return watchId;
166
+ }
167
+ /**
168
+ * Handle file watch events
169
+ */
170
+ async handleWatchEvent(event, outDir, config) {
171
+ const fileName = path.basename(event.filePath);
172
+ switch (event.type) {
173
+ case 'add':
174
+ logger.info(`New SVG detected: ${fileName}`);
175
+ await this.processWatchedFile(event.filePath, outDir, config);
176
+ break;
177
+ case 'change':
178
+ logger.info(`SVG updated: ${fileName}`);
179
+ await this.processWatchedFile(event.filePath, outDir, config);
180
+ break;
181
+ case 'unlink':
182
+ logger.info(`SVG removed: ${fileName}`);
183
+ await this.handleFileRemoval(event.filePath, outDir);
184
+ break;
185
+ }
186
+ }
187
+ /**
188
+ * Process a watched file
189
+ */
190
+ async processWatchedFile(filePath, outDir, config) {
191
+ try {
192
+ // Check if file is locked
193
+ if (this.lockService.isLocked(filePath)) {
194
+ logger.warn(`Skipped locked file: ${path.basename(filePath)}`);
195
+ return;
196
+ }
197
+ // Get configuration
198
+ const fullConfig = configService.readConfig();
199
+ const mergedConfig = { ...fullConfig, ...config };
200
+ // Process the file
201
+ await svgProcessor.processSVGFile(filePath, outDir, {
202
+ defaultWidth: mergedConfig.defaultWidth,
203
+ defaultHeight: mergedConfig.defaultHeight,
204
+ defaultFill: mergedConfig.defaultFill,
205
+ styleRules: Object.fromEntries(Object.entries(mergedConfig.styleRules || {}).filter(([_, v]) => v !== undefined)),
206
+ });
207
+ }
208
+ catch (error) {
209
+ logger.error(`Failed to process watched file ${path.basename(filePath)}:`, error);
210
+ }
211
+ }
212
+ /**
213
+ * Handle file removal in watch mode
214
+ */
215
+ async handleFileRemoval(filePath, outDir) {
216
+ try {
217
+ const componentName = svgProcessor.generateComponentName(path.basename(filePath));
218
+ const componentPath = path.join(outDir, `${componentName}.tsx`);
219
+ if (await FileSystem.exists(componentPath)) {
220
+ await FileSystem.unlink(componentPath);
221
+ logger.success(`Removed component: ${componentName}.tsx`);
222
+ }
223
+ }
224
+ catch (error) {
225
+ logger.error(`Failed to remove component for ${path.basename(filePath)}:`, error);
226
+ }
227
+ }
228
+ /**
229
+ * Stop watching files
230
+ */
231
+ stopWatching(watchId) {
232
+ if (watchId) {
233
+ fileWatcher.stopWatching(watchId);
234
+ this.activeWatchers.delete(watchId);
235
+ }
236
+ else {
237
+ // Stop all watchers
238
+ for (const id of this.activeWatchers) {
239
+ fileWatcher.stopWatching(id);
240
+ }
241
+ this.activeWatchers.clear();
242
+ }
243
+ }
244
+ /**
245
+ * Clean output directory
246
+ */
247
+ async clean(outDir) {
248
+ const targetDir = path.resolve(outDir);
249
+ if (!(await FileSystem.exists(targetDir))) {
250
+ logger.warn(`Directory not found: ${targetDir}`);
251
+ return;
252
+ }
253
+ await FileSystem.emptyDir(targetDir);
254
+ logger.success(`Cleaned all generated SVG components in: ${targetDir}`);
255
+ }
256
+ /**
257
+ * Generate index.ts file with all component exports
258
+ */
259
+ async generateIndexFile(outDir, svgFiles) {
260
+ try {
261
+ const componentNames = svgFiles.map(file => {
262
+ const baseName = path.basename(file, '.svg');
263
+ return svgProcessor.generateComponentName(baseName);
264
+ });
265
+ const indexContent = this.generateIndexContent(componentNames);
266
+ const indexPath = path.join(outDir, 'index.ts');
267
+ await FileSystem.writeFile(indexPath, indexContent, 'utf-8');
268
+ logger.success(`Generated index.ts with ${componentNames.length} component exports`);
269
+ }
270
+ catch (error) {
271
+ logger.error('Failed to generate index.ts:', error);
272
+ }
273
+ }
274
+ /**
275
+ * Generate the content for index.ts file
276
+ */
277
+ generateIndexContent(componentNames) {
278
+ const imports = componentNames
279
+ .map(name => `export { default as ${name} } from './${name}';`)
280
+ .join('\n');
281
+ const exportAll = `
282
+ // Export all components
283
+ export {
284
+ ${componentNames.map(name => ` ${name},`).join('\n')}
285
+ };
286
+
287
+ // Re-export for convenience
288
+ export default {
289
+ ${componentNames.map(name => ` ${name},`).join('\n')}
290
+ };
291
+ `;
292
+ return `/**
293
+ * SVG Components Index
294
+ * Generated by svger-cli
295
+ *
296
+ * Import individual components:
297
+ * import { ${componentNames[0] || 'ComponentName'} } from './components';
298
+ *
299
+ * Import all components:
300
+ * import * as Icons from './components';
301
+ * import Icons from './components'; // default export
302
+ */
303
+
304
+ ${imports}${exportAll}`;
305
+ }
306
+ /**
307
+ * Get service statistics
308
+ */
309
+ getStats() {
310
+ return {
311
+ activeWatchers: this.activeWatchers.size,
312
+ processingQueue: svgProcessor.getProcessingStats(),
313
+ watcherStats: fileWatcher.getWatchStats(),
314
+ };
315
+ }
316
+ /**
317
+ * Shutdown service
318
+ */
319
+ shutdown() {
320
+ this.stopWatching();
321
+ fileWatcher.shutdown();
322
+ svgProcessor.clearQueue();
323
+ logger.info('SVG service shutdown complete');
324
+ }
325
+ }
326
+ /**
327
+ * Simple file locking service
328
+ */
329
+ export class LockService {
330
+ static instance;
331
+ static LOCK_FILE = '.svg-lock';
332
+ cachedLocks = null;
333
+ constructor() { }
334
+ static getInstance() {
335
+ if (!LockService.instance) {
336
+ LockService.instance = new LockService();
337
+ }
338
+ return LockService.instance;
339
+ }
340
+ getLockFilePath() {
341
+ return path.resolve(LockService.LOCK_FILE);
342
+ }
343
+ readLockFile() {
344
+ if (this.cachedLocks) {
345
+ return this.cachedLocks;
346
+ }
347
+ try {
348
+ const data = FileSystem.readJSONSync(this.getLockFilePath());
349
+ this.cachedLocks = new Set(Array.isArray(data) ? data : []);
350
+ return this.cachedLocks;
351
+ }
352
+ catch {
353
+ this.cachedLocks = new Set();
354
+ return this.cachedLocks;
355
+ }
356
+ }
357
+ writeLockFile(locks) {
358
+ try {
359
+ FileSystem.writeJSONSync(this.getLockFilePath(), Array.from(locks), {
360
+ spaces: 2,
361
+ });
362
+ this.cachedLocks = locks;
363
+ }
364
+ catch (error) {
365
+ logger.error('Failed to write lock file:', error);
366
+ }
367
+ }
368
+ lockFiles(files) {
369
+ const fileNames = files.map(f => path.basename(f));
370
+ const current = this.readLockFile();
371
+ for (const fileName of fileNames) {
372
+ current.add(fileName);
373
+ }
374
+ this.writeLockFile(current);
375
+ logger.success(`Locked files: ${fileNames.join(', ')}`);
376
+ }
377
+ unlockFiles(files) {
378
+ const fileNames = files.map(f => path.basename(f));
379
+ const current = this.readLockFile();
380
+ for (const fileName of fileNames) {
381
+ current.delete(fileName);
382
+ }
383
+ this.writeLockFile(current);
384
+ logger.success(`Unlocked files: ${fileNames.join(', ')}`);
385
+ }
386
+ isLocked(file) {
387
+ const locks = this.readLockFile();
388
+ return locks.has(path.basename(file));
389
+ }
390
+ clearCache() {
391
+ this.cachedLocks = null;
392
+ }
393
+ }
394
+ // Export singleton instance
395
+ export const svgService = SVGService.getInstance();
@@ -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
  }
@@ -0,0 +1,146 @@
1
+ /**
2
+ * Type definitions for svger-cli
3
+ */
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
+ }
11
+ export interface SVGConfig {
12
+ source: string;
13
+ output: string | OutputConfig;
14
+ watch: boolean;
15
+ framework: FrameworkType;
16
+ typescript: boolean;
17
+ defaultWidth: number;
18
+ defaultHeight: number;
19
+ defaultFill: string;
20
+ exclude: string[];
21
+ styleRules: {
22
+ fill?: string;
23
+ stroke?: string;
24
+ [key: string]: string | undefined;
25
+ };
26
+ plugins?: PluginConfig[];
27
+ template?: TemplateConfig;
28
+ frameworkOptions?: FrameworkOptions;
29
+ errorHandling?: {
30
+ skipOnError: boolean;
31
+ logLevel: 'debug' | 'info' | 'warn' | 'error';
32
+ maxRetries: number;
33
+ };
34
+ performance?: {
35
+ batchSize: number;
36
+ parallel: boolean;
37
+ timeout: number;
38
+ enableCache: boolean;
39
+ };
40
+ }
41
+ export interface FrameworkOptions {
42
+ composition?: boolean;
43
+ setup?: boolean;
44
+ scriptSetup?: boolean;
45
+ standalone?: boolean;
46
+ moduleImport?: boolean;
47
+ signals?: boolean;
48
+ forwardRef?: boolean;
49
+ memo?: boolean;
50
+ customElement?: boolean;
51
+ shadowDom?: boolean;
52
+ cssModules?: boolean;
53
+ styledComponents?: boolean;
54
+ }
55
+ export interface BuildOptions {
56
+ src: string;
57
+ out: string;
58
+ config?: Partial<SVGConfig>;
59
+ }
60
+ export interface GenerateOptions {
61
+ svgFile: string;
62
+ outDir: string;
63
+ config?: Partial<SVGConfig>;
64
+ }
65
+ export interface WatchOptions {
66
+ src: string;
67
+ out: string;
68
+ config?: Partial<SVGConfig>;
69
+ }
70
+ export interface ComponentGenerationOptions {
71
+ componentName: string;
72
+ svgContent: string;
73
+ framework: FrameworkType;
74
+ typescript: boolean;
75
+ defaultWidth?: number;
76
+ defaultHeight?: number;
77
+ defaultFill?: string;
78
+ styleRules?: Record<string, string>;
79
+ template?: TemplateConfig;
80
+ frameworkOptions?: FrameworkOptions;
81
+ }
82
+ export interface TemplateConfig {
83
+ type: 'default' | 'custom';
84
+ path?: string;
85
+ options?: Record<string, any>;
86
+ }
87
+ export interface PluginConfig {
88
+ name: string;
89
+ options?: Record<string, any>;
90
+ }
91
+ export interface SVGProcessorResult {
92
+ success: boolean;
93
+ componentName: string;
94
+ filePath: string;
95
+ error?: Error;
96
+ }
97
+ export interface FileWatchEvent {
98
+ type: 'add' | 'change' | 'unlink';
99
+ filePath: string;
100
+ timestamp: number;
101
+ }
102
+ export interface ProcessingContext {
103
+ config: SVGConfig;
104
+ sourceDir: string;
105
+ outputDir: string;
106
+ fileQueue: string[];
107
+ locks: Set<string>;
108
+ cache?: Map<string, CachedComponent>;
109
+ }
110
+ export interface CachedComponent {
111
+ hash: string;
112
+ componentName: string;
113
+ filePath: string;
114
+ framework: FrameworkType;
115
+ timestamp: number;
116
+ svgHash: string;
117
+ }
118
+ export interface Logger {
119
+ info(message: string, ...args: any[]): void;
120
+ warn(message: string, ...args: any[]): void;
121
+ error(message: string, ...args: any[]): void;
122
+ success(message: string, ...args: any[]): void;
123
+ debug(message: string, ...args: any[]): void;
124
+ }
125
+ export interface Plugin {
126
+ name: string;
127
+ version: string;
128
+ process(content: string, options?: any): Promise<string>;
129
+ validate?(options?: any): boolean;
130
+ }
131
+ export interface Template {
132
+ name: string;
133
+ generate(options: ComponentGenerationOptions): string;
134
+ validate?(options: ComponentGenerationOptions): boolean;
135
+ }
136
+ export type FileSystemEvent = 'change' | 'rename';
137
+ export type LogLevel = 'debug' | 'info' | 'warn' | 'error';
138
+ export type ProcessingStatus = 'pending' | 'processing' | 'completed' | 'failed';
139
+ export interface ProcessingJob {
140
+ id: string;
141
+ filePath: string;
142
+ status: ProcessingStatus;
143
+ startTime: number;
144
+ endTime?: number;
145
+ error?: Error;
146
+ }
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Type definitions for svger-cli
3
+ */
4
+ export {};