svger-cli 2.0.0 → 2.0.2
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/cli.js +0 -0
- package/dist/core/error-handler.d.ts +63 -0
- package/dist/core/error-handler.js +224 -0
- package/dist/core/framework-templates.d.ts +17 -0
- package/{src/core/framework-templates.ts → dist/core/framework-templates.js} +100 -137
- package/dist/core/logger.d.ts +22 -0
- package/dist/core/logger.js +85 -0
- package/dist/core/performance-engine.d.ts +67 -0
- package/dist/core/performance-engine.js +251 -0
- package/dist/core/plugin-manager.d.ts +56 -0
- package/dist/core/plugin-manager.js +189 -0
- package/dist/core/style-compiler.d.ts +88 -0
- package/dist/core/style-compiler.js +466 -0
- package/dist/core/template-manager.d.ts +64 -0
- package/{src/core/template-manager.ts → dist/core/template-manager.js} +172 -255
- package/dist/index.d.ts +151 -0
- package/{src/index.ts → dist/index.js} +30 -108
- package/dist/processors/svg-processor.d.ts +67 -0
- package/dist/processors/svg-processor.js +225 -0
- package/dist/services/config.d.ts +55 -0
- package/dist/services/config.js +209 -0
- package/dist/services/file-watcher.d.ts +54 -0
- package/dist/services/file-watcher.js +180 -0
- package/dist/services/svg-service.d.ts +81 -0
- package/dist/services/svg-service.js +383 -0
- package/dist/types/index.d.ts +140 -0
- package/dist/types/index.js +4 -0
- package/dist/utils/native.d.ts +74 -0
- package/dist/utils/native.js +305 -0
- package/package.json +9 -3
- package/.svgconfig.json +0 -3
- package/CODE_OF_CONDUCT.md +0 -79
- package/CONTRIBUTING.md +0 -146
- package/TESTING.md +0 -143
- package/cli-framework.test.js +0 -16
- package/cli-test-angular/Arrowbenddownleft.component.ts +0 -27
- package/cli-test-angular/Vite.component.ts +0 -27
- package/cli-test-angular/index.ts +0 -25
- package/cli-test-output/Arrowbenddownleft.vue +0 -33
- package/cli-test-output/Vite.vue +0 -33
- package/cli-test-output/index.ts +0 -25
- package/cli-test-react/Arrowbenddownleft.tsx +0 -39
- package/cli-test-react/Vite.tsx +0 -39
- package/cli-test-react/index.ts +0 -25
- package/cli-test-svelte/Arrowbenddownleft.svelte +0 -22
- package/cli-test-svelte/Vite.svelte +0 -22
- package/cli-test-svelte/index.ts +0 -25
- package/docs/ADR-SVG-INTRGRATION-METHODS-001.adr.md +0 -157
- package/docs/ADR-SVG-INTRGRATION-METHODS-002.adr.md +0 -550
- package/docs/FRAMEWORK-GUIDE.md +0 -768
- package/docs/IMPLEMENTATION-SUMMARY.md +0 -376
- package/docs/TDR-SVG-INTRGRATION-METHODS-001.tdr.md +0 -115
- package/frameworks.test.js +0 -170
- package/my-svgs/ArrowBendDownLeft.svg +0 -6
- package/my-svgs/vite.svg +0 -1
- package/src/builder.ts +0 -104
- package/src/clean.ts +0 -21
- package/src/cli.ts +0 -221
- package/src/config.ts +0 -81
- package/src/core/error-handler.ts +0 -303
- package/src/core/logger.ts +0 -104
- package/src/core/performance-engine.ts +0 -327
- package/src/core/plugin-manager.ts +0 -228
- package/src/core/style-compiler.ts +0 -605
- package/src/lock.ts +0 -74
- package/src/processors/svg-processor.ts +0 -288
- package/src/services/config.ts +0 -241
- package/src/services/file-watcher.ts +0 -218
- package/src/services/svg-service.ts +0 -468
- package/src/templates/ComponentTemplate.ts +0 -57
- package/src/types/index.ts +0 -169
- package/src/utils/native.ts +0 -352
- package/src/watch.ts +0 -88
- package/test-output-mulit/TestIcon-angular-module.component.ts +0 -26
- package/test-output-mulit/TestIcon-angular-standalone.component.ts +0 -27
- package/test-output-mulit/TestIcon-lit.ts +0 -35
- package/test-output-mulit/TestIcon-preact.tsx +0 -38
- package/test-output-mulit/TestIcon-react.tsx +0 -35
- package/test-output-mulit/TestIcon-solid.tsx +0 -27
- package/test-output-mulit/TestIcon-svelte.svelte +0 -22
- package/test-output-mulit/TestIcon-vanilla.ts +0 -37
- package/test-output-mulit/TestIcon-vue-composition.vue +0 -33
- package/test-output-mulit/TestIcon-vue-options.vue +0 -31
- package/tsconfig.json +0 -18
package/dist/cli.js
CHANGED
|
File without changes
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enhanced error handling system with detailed error tracking and recovery
|
|
3
|
+
*/
|
|
4
|
+
export interface SVGError {
|
|
5
|
+
code: string;
|
|
6
|
+
message: string;
|
|
7
|
+
severity: 'low' | 'medium' | 'high' | 'critical';
|
|
8
|
+
context?: Record<string, any>;
|
|
9
|
+
timestamp: number;
|
|
10
|
+
stack?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface ErrorRecoveryStrategy {
|
|
13
|
+
canRecover(error: SVGError): boolean;
|
|
14
|
+
recover(error: SVGError, context?: any): Promise<any>;
|
|
15
|
+
}
|
|
16
|
+
export declare class SVGErrorHandler {
|
|
17
|
+
private static instance;
|
|
18
|
+
private errorHistory;
|
|
19
|
+
private recoveryStrategies;
|
|
20
|
+
private readonly maxHistorySize;
|
|
21
|
+
private constructor();
|
|
22
|
+
static getInstance(): SVGErrorHandler;
|
|
23
|
+
/**
|
|
24
|
+
* Handle an error with context and attempted recovery
|
|
25
|
+
*/
|
|
26
|
+
handleError(error: Error | SVGError, context?: Record<string, any>): Promise<{
|
|
27
|
+
recovered: boolean;
|
|
28
|
+
result?: any;
|
|
29
|
+
}>;
|
|
30
|
+
/**
|
|
31
|
+
* Register a custom error recovery strategy
|
|
32
|
+
*/
|
|
33
|
+
registerRecoveryStrategy(errorCode: string, strategy: ErrorRecoveryStrategy): void;
|
|
34
|
+
/**
|
|
35
|
+
* Get error statistics
|
|
36
|
+
*/
|
|
37
|
+
getErrorStats(): {
|
|
38
|
+
total: number;
|
|
39
|
+
bySeverity: Record<string, number>;
|
|
40
|
+
byCode: Record<string, number>;
|
|
41
|
+
recentErrors: SVGError[];
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Clear error history
|
|
45
|
+
*/
|
|
46
|
+
clearHistory(): void;
|
|
47
|
+
private normalizeError;
|
|
48
|
+
private categorizeError;
|
|
49
|
+
private determineSeverity;
|
|
50
|
+
private logError;
|
|
51
|
+
private addToHistory;
|
|
52
|
+
private attemptRecovery;
|
|
53
|
+
private setupDefaultStrategies;
|
|
54
|
+
}
|
|
55
|
+
export declare const errorHandler: SVGErrorHandler;
|
|
56
|
+
/**
|
|
57
|
+
* Utility function to wrap async operations with error handling
|
|
58
|
+
*/
|
|
59
|
+
export declare function withErrorHandling<T>(operation: () => Promise<T>, context?: Record<string, any>): Promise<T | null>;
|
|
60
|
+
/**
|
|
61
|
+
* Decorator for automatic error handling
|
|
62
|
+
*/
|
|
63
|
+
export declare function handleErrors(context?: Record<string, any>): (target: any, propertyName: string, descriptor: PropertyDescriptor) => void;
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
import { logger } from '../core/logger.js';
|
|
2
|
+
export class SVGErrorHandler {
|
|
3
|
+
static instance;
|
|
4
|
+
errorHistory = [];
|
|
5
|
+
recoveryStrategies = new Map();
|
|
6
|
+
maxHistorySize = 100;
|
|
7
|
+
constructor() {
|
|
8
|
+
this.setupDefaultStrategies();
|
|
9
|
+
}
|
|
10
|
+
static getInstance() {
|
|
11
|
+
if (!SVGErrorHandler.instance) {
|
|
12
|
+
SVGErrorHandler.instance = new SVGErrorHandler();
|
|
13
|
+
}
|
|
14
|
+
return SVGErrorHandler.instance;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Handle an error with context and attempted recovery
|
|
18
|
+
*/
|
|
19
|
+
async handleError(error, context) {
|
|
20
|
+
const svgError = this.normalizeError(error, context);
|
|
21
|
+
// Log error based on severity
|
|
22
|
+
this.logError(svgError);
|
|
23
|
+
// Add to history
|
|
24
|
+
this.addToHistory(svgError);
|
|
25
|
+
// Attempt recovery
|
|
26
|
+
const recoveryResult = await this.attemptRecovery(svgError, context);
|
|
27
|
+
return recoveryResult;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Register a custom error recovery strategy
|
|
31
|
+
*/
|
|
32
|
+
registerRecoveryStrategy(errorCode, strategy) {
|
|
33
|
+
this.recoveryStrategies.set(errorCode, strategy);
|
|
34
|
+
logger.debug(`Recovery strategy registered for error code: ${errorCode}`);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Get error statistics
|
|
38
|
+
*/
|
|
39
|
+
getErrorStats() {
|
|
40
|
+
const bySeverity = {};
|
|
41
|
+
const byCode = {};
|
|
42
|
+
this.errorHistory.forEach(error => {
|
|
43
|
+
bySeverity[error.severity] = (bySeverity[error.severity] || 0) + 1;
|
|
44
|
+
byCode[error.code] = (byCode[error.code] || 0) + 1;
|
|
45
|
+
});
|
|
46
|
+
return {
|
|
47
|
+
total: this.errorHistory.length,
|
|
48
|
+
bySeverity,
|
|
49
|
+
byCode,
|
|
50
|
+
recentErrors: this.errorHistory.slice(-10)
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Clear error history
|
|
55
|
+
*/
|
|
56
|
+
clearHistory() {
|
|
57
|
+
this.errorHistory = [];
|
|
58
|
+
logger.debug('Error history cleared');
|
|
59
|
+
}
|
|
60
|
+
// Private methods
|
|
61
|
+
normalizeError(error, context) {
|
|
62
|
+
if ('code' in error && 'severity' in error) {
|
|
63
|
+
return error;
|
|
64
|
+
}
|
|
65
|
+
// Convert regular Error to SVGError
|
|
66
|
+
const regularError = error;
|
|
67
|
+
return {
|
|
68
|
+
code: this.categorizeError(regularError),
|
|
69
|
+
message: regularError.message,
|
|
70
|
+
severity: this.determineSeverity(regularError),
|
|
71
|
+
context: context || {},
|
|
72
|
+
timestamp: Date.now(),
|
|
73
|
+
stack: regularError.stack
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
categorizeError(error) {
|
|
77
|
+
const message = error.message.toLowerCase();
|
|
78
|
+
if (message.includes('file not found') || message.includes('enoent')) {
|
|
79
|
+
return 'FILE_NOT_FOUND';
|
|
80
|
+
}
|
|
81
|
+
if (message.includes('permission') || message.includes('eacces')) {
|
|
82
|
+
return 'PERMISSION_DENIED';
|
|
83
|
+
}
|
|
84
|
+
if (message.includes('parse') || message.includes('syntax')) {
|
|
85
|
+
return 'PARSE_ERROR';
|
|
86
|
+
}
|
|
87
|
+
if (message.includes('timeout')) {
|
|
88
|
+
return 'TIMEOUT_ERROR';
|
|
89
|
+
}
|
|
90
|
+
if (message.includes('network') || message.includes('connection')) {
|
|
91
|
+
return 'NETWORK_ERROR';
|
|
92
|
+
}
|
|
93
|
+
if (message.includes('svg') && message.includes('invalid')) {
|
|
94
|
+
return 'INVALID_SVG';
|
|
95
|
+
}
|
|
96
|
+
return 'UNKNOWN_ERROR';
|
|
97
|
+
}
|
|
98
|
+
determineSeverity(error) {
|
|
99
|
+
const message = error.message.toLowerCase();
|
|
100
|
+
if (message.includes('critical') || message.includes('fatal')) {
|
|
101
|
+
return 'critical';
|
|
102
|
+
}
|
|
103
|
+
if (message.includes('file not found') || message.includes('permission')) {
|
|
104
|
+
return 'high';
|
|
105
|
+
}
|
|
106
|
+
if (message.includes('parse') || message.includes('invalid')) {
|
|
107
|
+
return 'medium';
|
|
108
|
+
}
|
|
109
|
+
return 'low';
|
|
110
|
+
}
|
|
111
|
+
logError(error) {
|
|
112
|
+
const logMessage = `[${error.code}] ${error.message}`;
|
|
113
|
+
switch (error.severity) {
|
|
114
|
+
case 'critical':
|
|
115
|
+
logger.error('CRITICAL:', logMessage, error.context);
|
|
116
|
+
break;
|
|
117
|
+
case 'high':
|
|
118
|
+
logger.error('HIGH:', logMessage, error.context);
|
|
119
|
+
break;
|
|
120
|
+
case 'medium':
|
|
121
|
+
logger.warn('MEDIUM:', logMessage, error.context);
|
|
122
|
+
break;
|
|
123
|
+
case 'low':
|
|
124
|
+
logger.info('LOW:', logMessage, error.context);
|
|
125
|
+
break;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
addToHistory(error) {
|
|
129
|
+
this.errorHistory.push(error);
|
|
130
|
+
// Maintain history size limit
|
|
131
|
+
if (this.errorHistory.length > this.maxHistorySize) {
|
|
132
|
+
this.errorHistory = this.errorHistory.slice(-this.maxHistorySize);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
async attemptRecovery(error, context) {
|
|
136
|
+
const strategy = this.recoveryStrategies.get(error.code);
|
|
137
|
+
if (!strategy) {
|
|
138
|
+
logger.debug(`No recovery strategy found for error code: ${error.code}`);
|
|
139
|
+
return { recovered: false };
|
|
140
|
+
}
|
|
141
|
+
try {
|
|
142
|
+
if (!strategy.canRecover(error)) {
|
|
143
|
+
logger.debug(`Recovery strategy declined to handle error: ${error.code}`);
|
|
144
|
+
return { recovered: false };
|
|
145
|
+
}
|
|
146
|
+
logger.info(`Attempting recovery for error: ${error.code}`);
|
|
147
|
+
const result = await strategy.recover(error, context);
|
|
148
|
+
logger.success(`Successfully recovered from error: ${error.code}`);
|
|
149
|
+
return { recovered: true, result };
|
|
150
|
+
}
|
|
151
|
+
catch (recoveryError) {
|
|
152
|
+
logger.error(`Recovery failed for error ${error.code}:`, recoveryError);
|
|
153
|
+
return { recovered: false };
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
setupDefaultStrategies() {
|
|
157
|
+
// File not found recovery
|
|
158
|
+
this.registerRecoveryStrategy('FILE_NOT_FOUND', {
|
|
159
|
+
canRecover: (error) => error.context?.filePath && error.context?.canSkip === true,
|
|
160
|
+
recover: async (error, context) => {
|
|
161
|
+
logger.warn(`Skipping missing file: ${error.context?.filePath}`);
|
|
162
|
+
return { skipped: true, filePath: error.context?.filePath };
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
// Invalid SVG recovery
|
|
166
|
+
this.registerRecoveryStrategy('INVALID_SVG', {
|
|
167
|
+
canRecover: (error) => error.context?.svgContent,
|
|
168
|
+
recover: async (error, context) => {
|
|
169
|
+
logger.info('Attempting to clean invalid SVG content');
|
|
170
|
+
// Basic SVG cleanup
|
|
171
|
+
let cleaned = error.context?.svgContent || '';
|
|
172
|
+
// Remove potentially problematic content
|
|
173
|
+
cleaned = cleaned
|
|
174
|
+
.replace(/<script[\s\S]*?<\/script>/gi, '') // Remove scripts
|
|
175
|
+
.replace(/<style[\s\S]*?<\/style>/gi, '') // Remove styles
|
|
176
|
+
.replace(/on\w+="[^"]*"/gi, '') // Remove event handlers
|
|
177
|
+
.replace(/javascript:[^"']*/gi, ''); // Remove javascript: URLs
|
|
178
|
+
return { cleanedContent: cleaned };
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
// Permission denied recovery
|
|
182
|
+
this.registerRecoveryStrategy('PERMISSION_DENIED', {
|
|
183
|
+
canRecover: (error) => error.context?.alternative,
|
|
184
|
+
recover: async (error, context) => {
|
|
185
|
+
logger.warn(`Using alternative path due to permission issue: ${error.context?.alternative}`);
|
|
186
|
+
return { alternativePath: error.context?.alternative };
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
logger.debug('Default error recovery strategies loaded');
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
// Export singleton instance and utilities
|
|
193
|
+
export const errorHandler = SVGErrorHandler.getInstance();
|
|
194
|
+
/**
|
|
195
|
+
* Utility function to wrap async operations with error handling
|
|
196
|
+
*/
|
|
197
|
+
export async function withErrorHandling(operation, context) {
|
|
198
|
+
try {
|
|
199
|
+
return await operation();
|
|
200
|
+
}
|
|
201
|
+
catch (error) {
|
|
202
|
+
const result = await errorHandler.handleError(error, context);
|
|
203
|
+
if (result.recovered) {
|
|
204
|
+
return result.result;
|
|
205
|
+
}
|
|
206
|
+
// Re-throw if not recovered and severity is high
|
|
207
|
+
const svgError = error;
|
|
208
|
+
if (svgError.severity === 'high' || svgError.severity === 'critical') {
|
|
209
|
+
throw error;
|
|
210
|
+
}
|
|
211
|
+
return null;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Decorator for automatic error handling
|
|
216
|
+
*/
|
|
217
|
+
export function handleErrors(context) {
|
|
218
|
+
return function (target, propertyName, descriptor) {
|
|
219
|
+
const method = descriptor.value;
|
|
220
|
+
descriptor.value = async function (...args) {
|
|
221
|
+
return withErrorHandling(() => method.apply(this, args), { method: propertyName, ...context });
|
|
222
|
+
};
|
|
223
|
+
};
|
|
224
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ComponentGenerationOptions, FrameworkType } from '../types/index.js';
|
|
2
|
+
export type { FrameworkType, FrameworkOptions } from '../types/index.js';
|
|
3
|
+
export declare class FrameworkTemplateEngine {
|
|
4
|
+
generateComponent(options: ComponentGenerationOptions): string;
|
|
5
|
+
getFileExtension(framework: FrameworkType, typescript?: boolean): string;
|
|
6
|
+
private parseSVG;
|
|
7
|
+
private generateReactComponent;
|
|
8
|
+
private generateVueComponent;
|
|
9
|
+
private generateSvelteComponent;
|
|
10
|
+
private generateAngularComponent;
|
|
11
|
+
private generateSolidComponent;
|
|
12
|
+
private generatePreactComponent;
|
|
13
|
+
private generateLitComponent;
|
|
14
|
+
private generateVanillaComponent;
|
|
15
|
+
private toKebabCase;
|
|
16
|
+
}
|
|
17
|
+
export declare const frameworkTemplateEngine: FrameworkTemplateEngine;
|
|
@@ -1,89 +1,65 @@
|
|
|
1
|
-
import { ComponentGenerationOptions, FrameworkType, FrameworkOptions } from '../types/index.js';
|
|
2
|
-
|
|
3
|
-
// Re-export types for convenience
|
|
4
|
-
export type { FrameworkType, FrameworkOptions } from '../types/index.js';
|
|
5
|
-
|
|
6
|
-
interface SVGAttributes {
|
|
7
|
-
viewBox?: string;
|
|
8
|
-
width?: string;
|
|
9
|
-
height?: string;
|
|
10
|
-
fill?: string;
|
|
11
|
-
stroke?: string;
|
|
12
|
-
xmlns?: string;
|
|
13
|
-
[key: string]: string | undefined;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
1
|
export class FrameworkTemplateEngine {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
throw new Error(`Unsupported framework: ${framework}`);
|
|
2
|
+
generateComponent(options) {
|
|
3
|
+
const { framework, componentName, svgContent, typescript = true, frameworkOptions = {} } = options;
|
|
4
|
+
switch (framework) {
|
|
5
|
+
case 'react':
|
|
6
|
+
return this.generateReactComponent(componentName, svgContent, typescript, frameworkOptions);
|
|
7
|
+
case 'vue':
|
|
8
|
+
return this.generateVueComponent(componentName, svgContent, typescript, frameworkOptions);
|
|
9
|
+
case 'svelte':
|
|
10
|
+
return this.generateSvelteComponent(componentName, svgContent, typescript);
|
|
11
|
+
case 'angular':
|
|
12
|
+
return this.generateAngularComponent(componentName, svgContent, typescript, frameworkOptions);
|
|
13
|
+
case 'solid':
|
|
14
|
+
return this.generateSolidComponent(componentName, svgContent, typescript);
|
|
15
|
+
case 'preact':
|
|
16
|
+
return this.generatePreactComponent(componentName, svgContent, typescript);
|
|
17
|
+
case 'lit':
|
|
18
|
+
return this.generateLitComponent(componentName, svgContent, typescript);
|
|
19
|
+
case 'vanilla':
|
|
20
|
+
return this.generateVanillaComponent(componentName, svgContent, typescript);
|
|
21
|
+
default:
|
|
22
|
+
throw new Error(`Unsupported framework: ${framework}`);
|
|
23
|
+
}
|
|
40
24
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
default:
|
|
61
|
-
return `${tsExt}`;
|
|
25
|
+
getFileExtension(framework, typescript = true) {
|
|
26
|
+
const tsExt = typescript ? 'ts' : 'js';
|
|
27
|
+
switch (framework) {
|
|
28
|
+
case 'react':
|
|
29
|
+
case 'preact':
|
|
30
|
+
case 'solid':
|
|
31
|
+
return typescript ? 'tsx' : 'jsx';
|
|
32
|
+
case 'vue':
|
|
33
|
+
return 'vue';
|
|
34
|
+
case 'svelte':
|
|
35
|
+
return 'svelte';
|
|
36
|
+
case 'angular':
|
|
37
|
+
return `component.${tsExt}`;
|
|
38
|
+
case 'lit':
|
|
39
|
+
case 'vanilla':
|
|
40
|
+
return `${tsExt}`;
|
|
41
|
+
default:
|
|
42
|
+
return `${tsExt}`;
|
|
43
|
+
}
|
|
62
44
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
45
|
+
parseSVG(svgContent) {
|
|
46
|
+
const svgMatch = svgContent.match(/<svg([^>]*)>([\s\S]*?)<\/svg>/);
|
|
47
|
+
if (!svgMatch) {
|
|
48
|
+
return { attributes: {}, innerContent: svgContent };
|
|
49
|
+
}
|
|
50
|
+
const attributesString = svgMatch[1];
|
|
51
|
+
const innerContent = svgMatch[2].trim();
|
|
52
|
+
const attributes = {};
|
|
53
|
+
const attrRegex = /(\w+(?:-\w+)*)="([^"]*)"/g;
|
|
54
|
+
let match;
|
|
55
|
+
while ((match = attrRegex.exec(attributesString)) !== null) {
|
|
56
|
+
attributes[match[1]] = match[2];
|
|
57
|
+
}
|
|
58
|
+
return { attributes, innerContent };
|
|
69
59
|
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
const attributes: SVGAttributes = {};
|
|
74
|
-
|
|
75
|
-
const attrRegex = /(\w+(?:-\w+)*)="([^"]*)"/g;
|
|
76
|
-
let match;
|
|
77
|
-
while ((match = attrRegex.exec(attributesString)) !== null) {
|
|
78
|
-
attributes[match[1]] = match[2];
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
return { attributes, innerContent };
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
private generateReactComponent(componentName: string, svgContent: string, typescript: boolean, options: FrameworkOptions): string {
|
|
85
|
-
const { attributes, innerContent } = this.parseSVG(svgContent);
|
|
86
|
-
return `import React from "react";
|
|
60
|
+
generateReactComponent(componentName, svgContent, typescript, options) {
|
|
61
|
+
const { attributes, innerContent } = this.parseSVG(svgContent);
|
|
62
|
+
return `import React from "react";
|
|
87
63
|
import type { SVGProps } from "react";
|
|
88
64
|
|
|
89
65
|
export interface ${componentName}Props extends SVGProps<SVGSVGElement> {
|
|
@@ -119,14 +95,12 @@ ${componentName}.displayName = "${componentName}";
|
|
|
119
95
|
|
|
120
96
|
export default ${componentName};
|
|
121
97
|
`;
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
if (scriptSetup && typescript) {
|
|
129
|
-
return `<template>
|
|
98
|
+
}
|
|
99
|
+
generateVueComponent(componentName, svgContent, typescript, options) {
|
|
100
|
+
const { attributes, innerContent } = this.parseSVG(svgContent);
|
|
101
|
+
const { scriptSetup = true } = options;
|
|
102
|
+
if (scriptSetup && typescript) {
|
|
103
|
+
return `<template>
|
|
130
104
|
<svg
|
|
131
105
|
:class="className"
|
|
132
106
|
:style="style"
|
|
@@ -160,9 +134,8 @@ withDefaults(defineProps<Props>(), {
|
|
|
160
134
|
});
|
|
161
135
|
</script>
|
|
162
136
|
`;
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
return `<template>
|
|
137
|
+
}
|
|
138
|
+
return `<template>
|
|
166
139
|
<svg
|
|
167
140
|
:class="className"
|
|
168
141
|
:style="style"
|
|
@@ -194,11 +167,10 @@ export default defineComponent({
|
|
|
194
167
|
});
|
|
195
168
|
</script>
|
|
196
169
|
`;
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
return `<script${typescript ? ' lang="ts"' : ''}>
|
|
170
|
+
}
|
|
171
|
+
generateSvelteComponent(componentName, svgContent, typescript) {
|
|
172
|
+
const { attributes, innerContent } = this.parseSVG(svgContent);
|
|
173
|
+
return `<script${typescript ? ' lang="ts"' : ''}>
|
|
202
174
|
export let className${typescript ? ': string' : ''} = '';
|
|
203
175
|
export let style${typescript ? ': string' : ''} = '';
|
|
204
176
|
export let width${typescript ? ': string | number' : ''} = ${attributes.width || 24};
|
|
@@ -221,14 +193,12 @@ export default defineComponent({
|
|
|
221
193
|
${innerContent}
|
|
222
194
|
</svg>
|
|
223
195
|
`;
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
return `import { Component, Input${standalone ? ', ChangeDetectionStrategy' : ''} } from '@angular/core';
|
|
196
|
+
}
|
|
197
|
+
generateAngularComponent(componentName, svgContent, typescript, options) {
|
|
198
|
+
const { attributes, innerContent } = this.parseSVG(svgContent);
|
|
199
|
+
const { standalone = true } = options;
|
|
200
|
+
const kebabName = this.toKebabCase(componentName);
|
|
201
|
+
return `import { Component, Input${standalone ? ', ChangeDetectionStrategy' : ''} } from '@angular/core';
|
|
232
202
|
|
|
233
203
|
@Component({
|
|
234
204
|
selector: '${kebabName}',
|
|
@@ -256,11 +226,10 @@ export class ${componentName}Component {
|
|
|
256
226
|
@Input() stroke: string = '';
|
|
257
227
|
}
|
|
258
228
|
`;
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
return `import { Component, JSX } from 'solid-js';
|
|
229
|
+
}
|
|
230
|
+
generateSolidComponent(componentName, svgContent, typescript) {
|
|
231
|
+
const { attributes, innerContent } = this.parseSVG(svgContent);
|
|
232
|
+
return `import { Component, JSX } from 'solid-js';
|
|
264
233
|
|
|
265
234
|
export interface ${componentName}Props extends JSX.SvgSVGAttributes<SVGSVGElement> {
|
|
266
235
|
className?: string;
|
|
@@ -288,11 +257,10 @@ const ${componentName}: Component<${componentName}Props> = (props) => (
|
|
|
288
257
|
|
|
289
258
|
export default ${componentName};
|
|
290
259
|
`;
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
return `import { h, FunctionComponent } from 'preact';
|
|
260
|
+
}
|
|
261
|
+
generatePreactComponent(componentName, svgContent, typescript) {
|
|
262
|
+
const { attributes, innerContent } = this.parseSVG(svgContent);
|
|
263
|
+
return `import { h, FunctionComponent } from 'preact';
|
|
296
264
|
import { JSX } from 'preact/jsx-runtime';
|
|
297
265
|
|
|
298
266
|
export interface ${componentName}Props extends JSX.SVGAttributes<SVGSVGElement> {
|
|
@@ -331,13 +299,11 @@ const ${componentName}: FunctionComponent<${componentName}Props> = ({
|
|
|
331
299
|
|
|
332
300
|
export default ${componentName};
|
|
333
301
|
`;
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
return `import { LitElement, html, css, svg } from 'lit';
|
|
302
|
+
}
|
|
303
|
+
generateLitComponent(componentName, svgContent, typescript) {
|
|
304
|
+
const { attributes, innerContent } = this.parseSVG(svgContent);
|
|
305
|
+
const kebabName = this.toKebabCase(componentName);
|
|
306
|
+
return `import { LitElement, html, css, svg } from 'lit';
|
|
341
307
|
import { customElement, property } from 'lit/decorators.js';
|
|
342
308
|
|
|
343
309
|
@customElement('${kebabName}')
|
|
@@ -373,11 +339,10 @@ declare global {
|
|
|
373
339
|
}
|
|
374
340
|
}
|
|
375
341
|
`;
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
return `export interface ${componentName}Options {
|
|
342
|
+
}
|
|
343
|
+
generateVanillaComponent(componentName, svgContent, typescript) {
|
|
344
|
+
const { attributes, innerContent } = this.parseSVG(svgContent);
|
|
345
|
+
return `export interface ${componentName}Options {
|
|
381
346
|
className?: string;
|
|
382
347
|
width?: string | number;
|
|
383
348
|
height?: string | number;
|
|
@@ -415,14 +380,12 @@ export function ${componentName}(options: ${componentName}Options = {}): SVGSVGE
|
|
|
415
380
|
return svg;
|
|
416
381
|
}
|
|
417
382
|
`;
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
}
|
|
383
|
+
}
|
|
384
|
+
toKebabCase(str) {
|
|
385
|
+
return str
|
|
386
|
+
.replace(/([a-z0-9])([A-Z])/g, '$1-$2')
|
|
387
|
+
.replace(/([A-Z])([A-Z])([a-z])/g, '$1-$2$3')
|
|
388
|
+
.toLowerCase();
|
|
389
|
+
}
|
|
426
390
|
}
|
|
427
|
-
|
|
428
391
|
export const frameworkTemplateEngine = new FrameworkTemplateEngine();
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Logger, LogLevel } from '../types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Professional logging service with configurable levels and formatted output
|
|
4
|
+
*/
|
|
5
|
+
export declare class LoggerService implements Logger {
|
|
6
|
+
private static instance;
|
|
7
|
+
private logLevel;
|
|
8
|
+
private enableColors;
|
|
9
|
+
private constructor();
|
|
10
|
+
static getInstance(): LoggerService;
|
|
11
|
+
setLogLevel(level: LogLevel): void;
|
|
12
|
+
setColors(enabled: boolean): void;
|
|
13
|
+
private shouldLog;
|
|
14
|
+
private formatMessage;
|
|
15
|
+
private getPrefix;
|
|
16
|
+
debug(message: string, ...args: any[]): void;
|
|
17
|
+
info(message: string, ...args: any[]): void;
|
|
18
|
+
warn(message: string, ...args: any[]): void;
|
|
19
|
+
error(message: string, ...args: any[]): void;
|
|
20
|
+
success(message: string, ...args: any[]): void;
|
|
21
|
+
}
|
|
22
|
+
export declare const logger: LoggerService;
|