svger-cli 2.0.2 → 2.0.4
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/.svgerconfig.example.json +119 -0
- package/CHANGELOG.md +64 -0
- package/DEVELOPMENT.md +353 -0
- package/README.md +430 -209
- package/SECURITY.md +69 -0
- package/dist/builder.js +16 -16
- package/dist/clean.js +2 -2
- package/dist/cli.js +38 -38
- package/dist/config.js +95 -12
- package/dist/core/error-handler.js +12 -9
- package/dist/core/framework-templates.js +5 -3
- package/dist/core/performance-engine.js +9 -8
- package/dist/core/plugin-manager.js +7 -5
- package/dist/core/style-compiler.js +17 -15
- package/dist/core/template-manager.js +14 -14
- package/dist/index.d.ts +8 -6
- package/dist/index.js +5 -5
- package/dist/lock.js +7 -7
- package/dist/processors/svg-processor.d.ts +9 -3
- package/dist/processors/svg-processor.js +56 -18
- package/dist/services/config.js +72 -20
- package/dist/services/file-watcher.js +3 -3
- package/dist/services/svg-service.js +34 -30
- package/dist/templates/ComponentTemplate.js +25 -25
- package/dist/types/index.d.ts +77 -19
- package/dist/utils/native.d.ts +32 -1
- package/dist/utils/native.js +47 -8
- package/dist/watch.d.ts +1 -1
- package/dist/watch.js +14 -14
- package/docs/ADR-SVG-INTRGRATION-METHODS-001.adr.md +157 -0
- package/docs/ADR-SVG-INTRGRATION-METHODS-002.adr.md +550 -0
- package/docs/FRAMEWORK-GUIDE.md +768 -0
- package/docs/IMPLEMENTATION-SUMMARY.md +376 -0
- package/docs/TDR-SVG-INTRGRATION-METHODS-001.tdr.md +115 -0
- package/package.json +155 -14
|
@@ -23,7 +23,7 @@ export class SVGStyleCompiler {
|
|
|
23
23
|
inline: {},
|
|
24
24
|
classes: [],
|
|
25
25
|
cssRules: [],
|
|
26
|
-
mediaQueries: []
|
|
26
|
+
mediaQueries: [],
|
|
27
27
|
};
|
|
28
28
|
// Get theme if specified
|
|
29
29
|
const theme = this.resolveTheme(options.theme);
|
|
@@ -76,7 +76,8 @@ export class SVGStyleCompiler {
|
|
|
76
76
|
const imports = hasCustomStyles
|
|
77
77
|
? `import React from 'react';\nimport type { SVGProps } from "react";`
|
|
78
78
|
: `import type { SVGProps } from "react";`;
|
|
79
|
-
const styledCSS = hasCustomStyles
|
|
79
|
+
const styledCSS = hasCustomStyles
|
|
80
|
+
? `
|
|
80
81
|
const ${componentName}Styles = \`
|
|
81
82
|
${compiled.cssRules.join('\n')}
|
|
82
83
|
${compiled.mediaQueries.join('\n')}
|
|
@@ -92,7 +93,8 @@ if (typeof document !== 'undefined') {
|
|
|
92
93
|
document.head.appendChild(style);
|
|
93
94
|
}
|
|
94
95
|
}
|
|
95
|
-
`
|
|
96
|
+
`
|
|
97
|
+
: '';
|
|
96
98
|
const inlineStyleObject = Object.keys(compiled.inline).length > 0
|
|
97
99
|
? `const defaultStyles = ${JSON.stringify(compiled.inline, null, 2)};`
|
|
98
100
|
: '';
|
|
@@ -295,28 +297,28 @@ if (typeof document !== 'undefined') {
|
|
|
295
297
|
danger: '#dc3545',
|
|
296
298
|
info: '#17a2b8',
|
|
297
299
|
light: '#f8f9fa',
|
|
298
|
-
dark: '#343a40'
|
|
300
|
+
dark: '#343a40',
|
|
299
301
|
},
|
|
300
302
|
sizes: {
|
|
301
303
|
xs: 12,
|
|
302
304
|
sm: 16,
|
|
303
305
|
md: 24,
|
|
304
306
|
lg: 32,
|
|
305
|
-
xl: 48
|
|
307
|
+
xl: 48,
|
|
306
308
|
},
|
|
307
309
|
spacing: {
|
|
308
310
|
1: '0.25rem',
|
|
309
311
|
2: '0.5rem',
|
|
310
312
|
3: '0.75rem',
|
|
311
313
|
4: '1rem',
|
|
312
|
-
5: '1.5rem'
|
|
314
|
+
5: '1.5rem',
|
|
313
315
|
},
|
|
314
316
|
breakpoints: {
|
|
315
317
|
sm: '576px',
|
|
316
318
|
md: '768px',
|
|
317
319
|
lg: '992px',
|
|
318
|
-
xl: '1200px'
|
|
319
|
-
}
|
|
320
|
+
xl: '1200px',
|
|
321
|
+
},
|
|
320
322
|
});
|
|
321
323
|
// Dark theme
|
|
322
324
|
this.registerTheme({
|
|
@@ -329,28 +331,28 @@ if (typeof document !== 'undefined') {
|
|
|
329
331
|
danger: '#dc3545',
|
|
330
332
|
info: '#0dcaf0',
|
|
331
333
|
light: '#212529',
|
|
332
|
-
dark: '#f8f9fa'
|
|
334
|
+
dark: '#f8f9fa',
|
|
333
335
|
},
|
|
334
336
|
sizes: {
|
|
335
337
|
xs: 12,
|
|
336
338
|
sm: 16,
|
|
337
339
|
md: 24,
|
|
338
340
|
lg: 32,
|
|
339
|
-
xl: 48
|
|
341
|
+
xl: 48,
|
|
340
342
|
},
|
|
341
343
|
spacing: {
|
|
342
344
|
1: '0.25rem',
|
|
343
345
|
2: '0.5rem',
|
|
344
346
|
3: '0.75rem',
|
|
345
347
|
4: '1rem',
|
|
346
|
-
5: '1.5rem'
|
|
348
|
+
5: '1.5rem',
|
|
347
349
|
},
|
|
348
350
|
breakpoints: {
|
|
349
351
|
sm: '576px',
|
|
350
352
|
md: '768px',
|
|
351
353
|
lg: '992px',
|
|
352
|
-
xl: '1200px'
|
|
353
|
-
}
|
|
354
|
+
xl: '1200px',
|
|
355
|
+
},
|
|
354
356
|
});
|
|
355
357
|
}
|
|
356
358
|
resolveTheme(theme) {
|
|
@@ -373,7 +375,7 @@ if (typeof document !== 'undefined') {
|
|
|
373
375
|
clipPath: 'clipPath',
|
|
374
376
|
mask: 'mask',
|
|
375
377
|
animation: 'animation',
|
|
376
|
-
transition: 'transition'
|
|
378
|
+
transition: 'transition',
|
|
377
379
|
};
|
|
378
380
|
for (const [cssProp, optionKey] of Object.entries(styleMap)) {
|
|
379
381
|
const value = options[optionKey];
|
|
@@ -416,7 +418,7 @@ if (typeof document !== 'undefined') {
|
|
|
416
418
|
sm: '576px',
|
|
417
419
|
md: '768px',
|
|
418
420
|
lg: '992px',
|
|
419
|
-
xl: '1200px'
|
|
421
|
+
xl: '1200px',
|
|
420
422
|
};
|
|
421
423
|
for (const [prop, value] of Object.entries(options)) {
|
|
422
424
|
if (this.isResponsiveValue(value)) {
|
|
@@ -25,37 +25,37 @@ export class TemplateManager {
|
|
|
25
25
|
this.registerTemplate({
|
|
26
26
|
name: 'react-functional',
|
|
27
27
|
generate: (options) => this.generateReactFunctional(options),
|
|
28
|
-
validate: (options) => !!options.componentName && !!options.svgContent
|
|
28
|
+
validate: (options) => !!options.componentName && !!options.svgContent,
|
|
29
29
|
});
|
|
30
30
|
// React Functional Component with forwardRef
|
|
31
31
|
this.registerTemplate({
|
|
32
32
|
name: 'react-forwardref',
|
|
33
33
|
generate: (options) => this.generateReactForwardRef(options),
|
|
34
|
-
validate: (options) => !!options.componentName && !!options.svgContent
|
|
34
|
+
validate: (options) => !!options.componentName && !!options.svgContent,
|
|
35
35
|
});
|
|
36
36
|
// React Class Component (legacy support)
|
|
37
37
|
this.registerTemplate({
|
|
38
38
|
name: 'react-class',
|
|
39
39
|
generate: (options) => this.generateReactClass(options),
|
|
40
|
-
validate: (options) => !!options.componentName && !!options.svgContent
|
|
40
|
+
validate: (options) => !!options.componentName && !!options.svgContent,
|
|
41
41
|
});
|
|
42
42
|
// Styled Components Template
|
|
43
43
|
this.registerTemplate({
|
|
44
44
|
name: 'styled-components',
|
|
45
45
|
generate: (options) => this.generateStyledComponents(options),
|
|
46
|
-
validate: (options) => !!options.componentName && !!options.svgContent
|
|
46
|
+
validate: (options) => !!options.componentName && !!options.svgContent,
|
|
47
47
|
});
|
|
48
48
|
// TypeScript Native (no React)
|
|
49
49
|
this.registerTemplate({
|
|
50
50
|
name: 'typescript-native',
|
|
51
51
|
generate: (options) => this.generateTypeScriptNative(options),
|
|
52
|
-
validate: (options) => !!options.componentName && !!options.svgContent
|
|
52
|
+
validate: (options) => !!options.componentName && !!options.svgContent,
|
|
53
53
|
});
|
|
54
54
|
// Enhanced Styled Template
|
|
55
55
|
this.registerTemplate({
|
|
56
56
|
name: 'enhanced-styled',
|
|
57
57
|
generate: (options) => this.generateEnhancedStyled(options),
|
|
58
|
-
validate: (options) => !!options.componentName && !!options.svgContent
|
|
58
|
+
validate: (options) => !!options.componentName && !!options.svgContent,
|
|
59
59
|
});
|
|
60
60
|
logger.debug('Built-in templates loaded');
|
|
61
61
|
}
|
|
@@ -97,7 +97,7 @@ export class TemplateManager {
|
|
|
97
97
|
name: templateName,
|
|
98
98
|
generate: (options) => {
|
|
99
99
|
return this.processStringTemplate(templateContent, options);
|
|
100
|
-
}
|
|
100
|
+
},
|
|
101
101
|
});
|
|
102
102
|
logger.info(`Custom template loaded: ${templateName}`);
|
|
103
103
|
}
|
|
@@ -127,7 +127,7 @@ export class TemplateManager {
|
|
|
127
127
|
* Standard React Functional Component
|
|
128
128
|
*/
|
|
129
129
|
generateReactFunctional(options) {
|
|
130
|
-
const { componentName, svgContent, defaultWidth = 24, defaultHeight = 24, defaultFill = 'currentColor' } = options;
|
|
130
|
+
const { componentName, svgContent, defaultWidth = 24, defaultHeight = 24, defaultFill = 'currentColor', } = options;
|
|
131
131
|
return `import React from "react";
|
|
132
132
|
import type { SVGProps } from "react";
|
|
133
133
|
|
|
@@ -173,7 +173,7 @@ export default ${componentName};
|
|
|
173
173
|
* React Functional Component with forwardRef
|
|
174
174
|
*/
|
|
175
175
|
generateReactForwardRef(options) {
|
|
176
|
-
const { componentName, svgContent, defaultWidth = 24, defaultHeight = 24, defaultFill = 'currentColor' } = options;
|
|
176
|
+
const { componentName, svgContent, defaultWidth = 24, defaultHeight = 24, defaultFill = 'currentColor', } = options;
|
|
177
177
|
return `import { forwardRef } from "react";
|
|
178
178
|
import type { SVGProps } from "react";
|
|
179
179
|
|
|
@@ -208,7 +208,7 @@ export default ${componentName};
|
|
|
208
208
|
* React Class Component (legacy)
|
|
209
209
|
*/
|
|
210
210
|
generateReactClass(options) {
|
|
211
|
-
const { componentName, svgContent, defaultWidth = 24, defaultHeight = 24, defaultFill = 'currentColor' } = options;
|
|
211
|
+
const { componentName, svgContent, defaultWidth = 24, defaultHeight = 24, defaultFill = 'currentColor', } = options;
|
|
212
212
|
return `import { Component } from "react";
|
|
213
213
|
import type { SVGProps } from "react";
|
|
214
214
|
|
|
@@ -242,7 +242,7 @@ export default ${componentName};
|
|
|
242
242
|
* Styled Components Template
|
|
243
243
|
*/
|
|
244
244
|
generateStyledComponents(options) {
|
|
245
|
-
const { componentName, svgContent, defaultWidth = 24, defaultHeight = 24, defaultFill = 'currentColor' } = options;
|
|
245
|
+
const { componentName, svgContent, defaultWidth = 24, defaultHeight = 24, defaultFill = 'currentColor', } = options;
|
|
246
246
|
return `import styled from "styled-components";
|
|
247
247
|
import type { SVGProps } from "react";
|
|
248
248
|
|
|
@@ -275,7 +275,7 @@ export default ${componentName};
|
|
|
275
275
|
* TypeScript Native (no React dependencies)
|
|
276
276
|
*/
|
|
277
277
|
generateTypeScriptNative(options) {
|
|
278
|
-
const { componentName, svgContent, defaultWidth = 24, defaultHeight = 24, defaultFill = 'currentColor' } = options;
|
|
278
|
+
const { componentName, svgContent, defaultWidth = 24, defaultHeight = 24, defaultFill = 'currentColor', } = options;
|
|
279
279
|
return `/**
|
|
280
280
|
* ${componentName} SVG Icon (Native TypeScript)
|
|
281
281
|
* Generated by svger-cli
|
|
@@ -328,7 +328,7 @@ export default ${componentName};
|
|
|
328
328
|
...options,
|
|
329
329
|
defaultWidth: options.defaultWidth || 24,
|
|
330
330
|
defaultHeight: options.defaultHeight || 24,
|
|
331
|
-
defaultFill: options.defaultFill || 'currentColor'
|
|
331
|
+
defaultFill: options.defaultFill || 'currentColor',
|
|
332
332
|
};
|
|
333
333
|
let processed = template;
|
|
334
334
|
// Replace variables in the format {{variableName}}
|
|
@@ -342,7 +342,7 @@ export default ${componentName};
|
|
|
342
342
|
* Enhanced Styled Template with comprehensive styling support
|
|
343
343
|
*/
|
|
344
344
|
generateEnhancedStyled(options) {
|
|
345
|
-
const { componentName, svgContent, defaultWidth = 24, defaultHeight = 24, defaultFill = 'currentColor' } = options;
|
|
345
|
+
const { componentName, svgContent, defaultWidth = 24, defaultHeight = 24, defaultFill = 'currentColor', } = options;
|
|
346
346
|
return `import React from "react";
|
|
347
347
|
import type { SVGProps } from "react";
|
|
348
348
|
|
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
|
|
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
|
|
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
|
|
2
|
-
import path from
|
|
3
|
-
const LOCK_FILE =
|
|
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(),
|
|
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),
|
|
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
|
|
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,29 @@ 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
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
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
|
+
}
|
|
79
|
+
case 'pascal':
|
|
80
|
+
default: {
|
|
81
|
+
// Default to PascalCase
|
|
82
|
+
const componentName = toPascalCase(baseName);
|
|
83
|
+
// Ensure component name starts with uppercase letter
|
|
84
|
+
if (!/^[A-Z]/.test(componentName)) {
|
|
85
|
+
return `Svg${componentName}`;
|
|
86
|
+
}
|
|
87
|
+
return componentName;
|
|
88
|
+
}
|
|
73
89
|
}
|
|
74
|
-
return componentName;
|
|
75
90
|
}
|
|
76
91
|
/**
|
|
77
92
|
* Generate React component from SVG content
|
|
@@ -88,7 +103,7 @@ export class SVGProcessor {
|
|
|
88
103
|
svgContent: processedContent,
|
|
89
104
|
framework: options.framework || 'react',
|
|
90
105
|
typescript: options.typescript !== undefined ? options.typescript : true,
|
|
91
|
-
...options
|
|
106
|
+
...options,
|
|
92
107
|
};
|
|
93
108
|
// Use framework template engine directly
|
|
94
109
|
const component = frameworkTemplateEngine.generateComponent(fullOptions);
|
|
@@ -112,7 +127,7 @@ export class SVGProcessor {
|
|
|
112
127
|
const component = frameworkTemplateEngine.generateComponent({
|
|
113
128
|
...options,
|
|
114
129
|
componentName,
|
|
115
|
-
svgContent: optimizedContent
|
|
130
|
+
svgContent: optimizedContent,
|
|
116
131
|
});
|
|
117
132
|
logger.debug(`Generated ${options.framework} component: ${componentName}`);
|
|
118
133
|
return component;
|
|
@@ -141,6 +156,26 @@ export class SVGProcessor {
|
|
|
141
156
|
throw error;
|
|
142
157
|
}
|
|
143
158
|
}
|
|
159
|
+
/**
|
|
160
|
+
* Generate filename from component name using naming convention
|
|
161
|
+
*/
|
|
162
|
+
generateFileName(componentName, extension, namingConvention) {
|
|
163
|
+
let fileName;
|
|
164
|
+
switch (namingConvention) {
|
|
165
|
+
case 'kebab':
|
|
166
|
+
fileName = toKebabCase(componentName);
|
|
167
|
+
break;
|
|
168
|
+
case 'camel':
|
|
169
|
+
fileName = toCamelCase(componentName);
|
|
170
|
+
break;
|
|
171
|
+
case 'pascal':
|
|
172
|
+
default:
|
|
173
|
+
// Default to PascalCase (same as component name)
|
|
174
|
+
fileName = componentName;
|
|
175
|
+
break;
|
|
176
|
+
}
|
|
177
|
+
return `${fileName}.${extension}`;
|
|
178
|
+
}
|
|
144
179
|
/**
|
|
145
180
|
* Process a single SVG file
|
|
146
181
|
*/
|
|
@@ -150,15 +185,16 @@ export class SVGProcessor {
|
|
|
150
185
|
id: jobId,
|
|
151
186
|
filePath: svgFilePath,
|
|
152
187
|
status: 'processing',
|
|
153
|
-
startTime: Date.now()
|
|
188
|
+
startTime: Date.now(),
|
|
154
189
|
};
|
|
155
190
|
this.processingQueue.set(jobId, job);
|
|
156
191
|
logger.debug(`Processing SVG file: ${svgFilePath}`);
|
|
157
192
|
try {
|
|
158
193
|
// Read SVG content
|
|
159
194
|
const svgContent = await FileSystem.readFile(svgFilePath, 'utf-8');
|
|
160
|
-
// Generate component name
|
|
161
|
-
const
|
|
195
|
+
// Generate component name using the specified naming convention
|
|
196
|
+
const namingConvention = options.namingConvention || 'pascal';
|
|
197
|
+
const componentName = this.generateComponentName(path.basename(svgFilePath), namingConvention);
|
|
162
198
|
// Generate component code
|
|
163
199
|
const componentCode = await this.generateComponent(componentName, svgContent, options);
|
|
164
200
|
// Ensure output directory exists
|
|
@@ -167,8 +203,10 @@ export class SVGProcessor {
|
|
|
167
203
|
const framework = options.framework || 'react';
|
|
168
204
|
const typescript = options.typescript !== undefined ? options.typescript : true;
|
|
169
205
|
const fileExtension = frameworkTemplateEngine.getFileExtension(framework, typescript);
|
|
206
|
+
// Generate filename using naming convention from options
|
|
207
|
+
const fileName = this.generateFileName(componentName, fileExtension, namingConvention);
|
|
170
208
|
// Write component file
|
|
171
|
-
const outputFilePath = path.join(outputDir,
|
|
209
|
+
const outputFilePath = path.join(outputDir, fileName);
|
|
172
210
|
await FileSystem.writeFile(outputFilePath, componentCode, 'utf-8');
|
|
173
211
|
// Update job status
|
|
174
212
|
job.status = 'completed';
|
|
@@ -176,9 +214,9 @@ export class SVGProcessor {
|
|
|
176
214
|
const result = {
|
|
177
215
|
success: true,
|
|
178
216
|
componentName,
|
|
179
|
-
filePath: outputFilePath
|
|
217
|
+
filePath: outputFilePath,
|
|
180
218
|
};
|
|
181
|
-
logger.success(`Generated component: ${
|
|
219
|
+
logger.success(`Generated component: ${fileName}`);
|
|
182
220
|
return result;
|
|
183
221
|
}
|
|
184
222
|
catch (error) {
|
|
@@ -189,7 +227,7 @@ export class SVGProcessor {
|
|
|
189
227
|
success: false,
|
|
190
228
|
componentName: '',
|
|
191
229
|
filePath: svgFilePath,
|
|
192
|
-
error: error
|
|
230
|
+
error: error,
|
|
193
231
|
};
|
|
194
232
|
logger.error(`Failed to process ${svgFilePath}:`, error);
|
|
195
233
|
return result;
|