svger-cli 2.0.8 → 3.0.0

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
@@ -146,6 +146,36 @@ export declare const SVGER: {
146
146
  */
147
147
  export declare const VERSION = "2.0.0";
148
148
  export declare const PACKAGE_NAME = "svger-cli";
149
+ /**
150
+ * Webpack Plugin - Official webpack integration for SVGER-CLI
151
+ * Provides: HMR support, asset processing, and webpack loader
152
+ */
153
+ export { SvgerWebpackPlugin, svgerLoader, default as webpackPlugin, } from './integrations/webpack.js';
154
+ /**
155
+ * Vite Plugin - Official Vite integration for SVGER-CLI
156
+ * Provides: HMR support, virtual modules, and dev server integration
157
+ */
158
+ export { svgerVitePlugin, default as vitePlugin } from './integrations/vite.js';
159
+ /**
160
+ * Rollup Plugin - Official Rollup integration for SVGER-CLI
161
+ * Provides: Bundle optimization and tree-shaking support
162
+ */
163
+ export { svgerRollupPlugin, default as rollupPlugin, } from './integrations/rollup.js';
164
+ /**
165
+ * Babel Plugin - Official Babel integration for SVGER-CLI
166
+ * Provides: SVG import transformation and component generation
167
+ */
168
+ export { svgerBabelPlugin, createBabelPlugin, default as babelPlugin, } from './integrations/babel.js';
169
+ /**
170
+ * Next.js Plugin - Official Next.js integration for SVGER-CLI
171
+ * Provides: SSR support, webpack integration, and HMR
172
+ */
173
+ export { withSvger, SvgerNextJsPlugin, configureSvgImports, default as nextjsPlugin, } from './integrations/nextjs.js';
174
+ /**
175
+ * Jest Preset - Official Jest integration for SVGER-CLI
176
+ * Provides: SVG transformers and test configuration
177
+ */
178
+ export { svgerJestTransformer, jestPreset, createJestTransformer, default as jestTransformer, } from './integrations/jest-preset.js';
149
179
  /**
150
180
  * Default export - Primary SVG processor instance for quick access
151
181
  * Most common entry point for programmatic usage
package/dist/index.js CHANGED
@@ -148,6 +148,39 @@ export const SVGER = {
148
148
  export const VERSION = '2.0.0';
149
149
  export const PACKAGE_NAME = 'svger-cli';
150
150
  // ============================================================================
151
+ // BUILD TOOL INTEGRATIONS
152
+ // ============================================================================
153
+ /**
154
+ * Webpack Plugin - Official webpack integration for SVGER-CLI
155
+ * Provides: HMR support, asset processing, and webpack loader
156
+ */
157
+ export { SvgerWebpackPlugin, svgerLoader, default as webpackPlugin, } from './integrations/webpack.js';
158
+ /**
159
+ * Vite Plugin - Official Vite integration for SVGER-CLI
160
+ * Provides: HMR support, virtual modules, and dev server integration
161
+ */
162
+ export { svgerVitePlugin, default as vitePlugin } from './integrations/vite.js';
163
+ /**
164
+ * Rollup Plugin - Official Rollup integration for SVGER-CLI
165
+ * Provides: Bundle optimization and tree-shaking support
166
+ */
167
+ export { svgerRollupPlugin, default as rollupPlugin, } from './integrations/rollup.js';
168
+ /**
169
+ * Babel Plugin - Official Babel integration for SVGER-CLI
170
+ * Provides: SVG import transformation and component generation
171
+ */
172
+ export { svgerBabelPlugin, createBabelPlugin, default as babelPlugin, } from './integrations/babel.js';
173
+ /**
174
+ * Next.js Plugin - Official Next.js integration for SVGER-CLI
175
+ * Provides: SSR support, webpack integration, and HMR
176
+ */
177
+ export { withSvger, SvgerNextJsPlugin, configureSvgImports, default as nextjsPlugin, } from './integrations/nextjs.js';
178
+ /**
179
+ * Jest Preset - Official Jest integration for SVGER-CLI
180
+ * Provides: SVG transformers and test configuration
181
+ */
182
+ export { svgerJestTransformer, jestPreset, createJestTransformer, default as jestTransformer, } from './integrations/jest-preset.js';
183
+ // ============================================================================
151
184
  // DEFAULT EXPORT
152
185
  // ============================================================================
153
186
  /**
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Official Babel Plugin for SVGER-CLI
3
+ *
4
+ * Transforms SVG imports into framework components during Babel transpilation.
5
+ * Works with any Babel-based build process including standalone Babel, Create React App,
6
+ * and other tools that use Babel under the hood.
7
+ *
8
+ * @example
9
+ * ```js
10
+ * // babel.config.js
11
+ * const { svgerBabelPlugin } = require('svger-cli/babel');
12
+ *
13
+ * module.exports = {
14
+ * plugins: [
15
+ * [svgerBabelPlugin, {
16
+ * source: './src/icons',
17
+ * output: './src/components/icons',
18
+ * framework: 'react',
19
+ * typescript: true
20
+ * }]
21
+ * ]
22
+ * };
23
+ * ```
24
+ *
25
+ * @example
26
+ * ```js
27
+ * // Direct SVG import transformation
28
+ * import Icon from './icon.svg';
29
+ * // Transforms to:
30
+ * import Icon from './components/icons/Icon';
31
+ * ```
32
+ */
33
+ import type { BabelPluginOptions } from '../types/integrations.js';
34
+ /**
35
+ * Babel Plugin for SVGER-CLI
36
+ *
37
+ * This plugin processes SVG files and transforms SVG imports to component imports.
38
+ * It can run in two modes:
39
+ * - Pre-build: Process all SVGs before Babel transformation
40
+ * - On-demand: Transform SVG imports as they're encountered
41
+ */
42
+ export declare function svgerBabelPlugin(api: any, options?: BabelPluginOptions): any;
43
+ /**
44
+ * Create a Babel plugin instance with preset options
45
+ *
46
+ * @example
47
+ * ```js
48
+ * const plugin = createBabelPlugin({
49
+ * source: './icons',
50
+ * framework: 'react'
51
+ * });
52
+ * ```
53
+ */
54
+ export declare function createBabelPlugin(options?: BabelPluginOptions): (api: any) => any;
55
+ /**
56
+ * Default export for convenient usage
57
+ */
58
+ export default svgerBabelPlugin;
@@ -0,0 +1,221 @@
1
+ /**
2
+ * Official Babel Plugin for SVGER-CLI
3
+ *
4
+ * Transforms SVG imports into framework components during Babel transpilation.
5
+ * Works with any Babel-based build process including standalone Babel, Create React App,
6
+ * and other tools that use Babel under the hood.
7
+ *
8
+ * @example
9
+ * ```js
10
+ * // babel.config.js
11
+ * const { svgerBabelPlugin } = require('svger-cli/babel');
12
+ *
13
+ * module.exports = {
14
+ * plugins: [
15
+ * [svgerBabelPlugin, {
16
+ * source: './src/icons',
17
+ * output: './src/components/icons',
18
+ * framework: 'react',
19
+ * typescript: true
20
+ * }]
21
+ * ]
22
+ * };
23
+ * ```
24
+ *
25
+ * @example
26
+ * ```js
27
+ * // Direct SVG import transformation
28
+ * import Icon from './icon.svg';
29
+ * // Transforms to:
30
+ * import Icon from './components/icons/Icon';
31
+ * ```
32
+ */
33
+ import path from 'path';
34
+ import { FileSystem } from '../utils/native.js';
35
+ import { svgProcessor } from '../processors/svg-processor.js';
36
+ import { configService } from '../services/config.js';
37
+ import { logger } from '../core/logger.js';
38
+ const PLUGIN_NAME = 'svger-babel-plugin';
39
+ /**
40
+ * Process all SVG files in the source directory
41
+ */
42
+ async function processAllSVGs(options, processedFiles) {
43
+ const sourcePath = path.resolve(options.source);
44
+ const outputPath = path.resolve(options.output);
45
+ if (!(await FileSystem.exists(sourcePath))) {
46
+ logger.warn(`Source directory not found: ${sourcePath}`);
47
+ return [];
48
+ }
49
+ const files = await FileSystem.readDir(sourcePath);
50
+ const svgFiles = files.filter(file => file.endsWith('.svg'));
51
+ const results = [];
52
+ for (const file of svgFiles) {
53
+ const filePath = path.join(sourcePath, file);
54
+ if (processedFiles.has(filePath))
55
+ continue;
56
+ try {
57
+ const svgContent = await FileSystem.readFile(filePath, 'utf-8');
58
+ const componentName = svgProcessor.generateComponentName(file, 'pascal');
59
+ const config = configService.readConfig();
60
+ const component = await svgProcessor.generateComponent(componentName, svgContent, {
61
+ framework: options.framework,
62
+ typescript: options.typescript,
63
+ defaultWidth: config.defaultWidth,
64
+ defaultHeight: config.defaultHeight,
65
+ defaultFill: config.defaultFill,
66
+ styleRules: config.styleRules || {},
67
+ });
68
+ const ext = options.typescript ? 'tsx' : 'jsx';
69
+ const outputFile = path.join(outputPath, `${componentName}.${ext}`);
70
+ await FileSystem.ensureDir(path.dirname(outputFile));
71
+ await FileSystem.writeFile(outputFile, component);
72
+ processedFiles.add(filePath);
73
+ results.push({
74
+ success: true,
75
+ outputPath: outputFile,
76
+ componentName,
77
+ });
78
+ }
79
+ catch (error) {
80
+ logger.error(`Failed to process ${file}:`, error);
81
+ results.push({
82
+ success: false,
83
+ error: error,
84
+ });
85
+ }
86
+ }
87
+ // Generate index file if enabled
88
+ if (options.generateIndex && results.length > 0) {
89
+ try {
90
+ await generateIndexFile(outputPath, results, options);
91
+ }
92
+ catch (error) {
93
+ logger.error('Failed to generate index file:', error);
94
+ }
95
+ }
96
+ return results;
97
+ }
98
+ /**
99
+ * Generate index file with all exports
100
+ */
101
+ async function generateIndexFile(outputDir, results, options) {
102
+ const extension = options.typescript ? 'ts' : 'js';
103
+ const exports = results
104
+ .filter(r => r.componentName)
105
+ .map(r => `export { default as ${r.componentName} } from './${r.componentName}';`)
106
+ .join('\n');
107
+ const indexPath = path.join(outputDir, `index.${extension}`);
108
+ await FileSystem.writeFile(indexPath, exports, 'utf-8');
109
+ logger.debug(`Generated index file: ${indexPath}`);
110
+ }
111
+ /**
112
+ * Transform SVG import path to component path
113
+ */
114
+ function transformSVGImport(sourcePath, options) {
115
+ if (!sourcePath.endsWith('.svg'))
116
+ return null;
117
+ const absoluteOutput = path.resolve(options.output);
118
+ // Extract filename without extension
119
+ const fileName = path.basename(sourcePath, '.svg');
120
+ const componentName = svgProcessor.generateComponentName(fileName, 'pascal');
121
+ // Calculate relative path from output to component
122
+ const ext = options.typescript ? 'tsx' : 'jsx';
123
+ return path.join(absoluteOutput, `${componentName}.${ext}`);
124
+ }
125
+ /**
126
+ * Babel Plugin for SVGER-CLI
127
+ *
128
+ * This plugin processes SVG files and transforms SVG imports to component imports.
129
+ * It can run in two modes:
130
+ * - Pre-build: Process all SVGs before Babel transformation
131
+ * - On-demand: Transform SVG imports as they're encountered
132
+ */
133
+ export function svgerBabelPlugin(api, options = {}) {
134
+ const config = configService.readConfig();
135
+ const pluginOptions = {
136
+ source: options.source || config.source || './src/icons',
137
+ output: options.output || config.output || './src/components/icons',
138
+ framework: options.framework || config.framework || 'react',
139
+ typescript: options.typescript !== undefined ? options.typescript : config.typescript,
140
+ config: options.config || {},
141
+ include: options.include || ['**/*.svg'],
142
+ exclude: options.exclude || ['node_modules/**'],
143
+ transformImports: options.transformImports !== undefined ? options.transformImports : true,
144
+ processOnInit: options.processOnInit !== undefined ? options.processOnInit : true,
145
+ generateIndex: options.generateIndex !== undefined ? options.generateIndex : true,
146
+ };
147
+ const processedFiles = new Set();
148
+ let initialized = false;
149
+ return {
150
+ name: PLUGIN_NAME,
151
+ // Babel visitor pattern
152
+ visitor: {
153
+ // Process before any transformations if enabled
154
+ Program: {
155
+ enter: async () => {
156
+ if (!initialized && pluginOptions.processOnInit) {
157
+ initialized = true;
158
+ logger.info('SVGER Babel Plugin: Processing SVG files...');
159
+ const results = await processAllSVGs(pluginOptions, processedFiles);
160
+ const successCount = results.filter(r => r.success).length;
161
+ if (successCount > 0) {
162
+ logger.info(`SVGER Babel Plugin: Processed ${successCount} SVG files`);
163
+ }
164
+ }
165
+ },
166
+ },
167
+ // Transform import declarations
168
+ ImportDeclaration(nodePath) {
169
+ if (!pluginOptions.transformImports)
170
+ return;
171
+ const source = nodePath.node.source.value;
172
+ if (typeof source === 'string' && source.endsWith('.svg')) {
173
+ const newPath = transformSVGImport(source, pluginOptions);
174
+ if (newPath) {
175
+ // Replace the import source
176
+ nodePath.node.source.value = newPath.replace(/\.(tsx|jsx)$/, '');
177
+ logger.debug(`SVGER Babel Plugin: Transformed ${source} -> ${newPath}`);
178
+ }
179
+ }
180
+ },
181
+ // Handle dynamic imports
182
+ CallExpression(nodePath) {
183
+ if (!pluginOptions.transformImports)
184
+ return;
185
+ const callee = nodePath.node.callee;
186
+ // Check for import() calls
187
+ if (callee.type === 'Import') {
188
+ const args = nodePath.node.arguments;
189
+ if (args.length > 0 && args[0].type === 'StringLiteral') {
190
+ const source = args[0].value;
191
+ if (source.endsWith('.svg')) {
192
+ const newPath = transformSVGImport(source, pluginOptions);
193
+ if (newPath) {
194
+ args[0].value = newPath.replace(/\.(tsx|jsx)$/, '');
195
+ logger.debug(`SVGER Babel Plugin: Transformed dynamic import ${source} -> ${newPath}`);
196
+ }
197
+ }
198
+ }
199
+ }
200
+ },
201
+ },
202
+ };
203
+ }
204
+ /**
205
+ * Create a Babel plugin instance with preset options
206
+ *
207
+ * @example
208
+ * ```js
209
+ * const plugin = createBabelPlugin({
210
+ * source: './icons',
211
+ * framework: 'react'
212
+ * });
213
+ * ```
214
+ */
215
+ export function createBabelPlugin(options = {}) {
216
+ return (api) => svgerBabelPlugin(api, options);
217
+ }
218
+ /**
219
+ * Default export for convenient usage
220
+ */
221
+ export default svgerBabelPlugin;
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Official Jest Preset for SVGER-CLI
3
+ *
4
+ * Provides Jest transformers and configuration for testing SVG components
5
+ * with full framework support.
6
+ *
7
+ * @example
8
+ * ```js
9
+ * // jest.config.js
10
+ * module.exports = {
11
+ * preset: 'svger-cli/jest',
12
+ * // or manually configure:
13
+ * transform: {
14
+ * '\\.svg$': 'svger-cli/jest-transformer'
15
+ * }
16
+ * };
17
+ * ```
18
+ */
19
+ import type { JestPresetOptions } from '../types/integrations.js';
20
+ /**
21
+ * Jest transformer for SVG files
22
+ */
23
+ export declare const svgerJestTransformer: {
24
+ process(sourceText: string, sourcePath: string, options: any): {
25
+ code: string;
26
+ };
27
+ };
28
+ /**
29
+ * Jest preset configuration
30
+ */
31
+ export declare const jestPreset: {
32
+ transform: {
33
+ '\\.svg$': {}[];
34
+ };
35
+ moduleNameMapper: {
36
+ '\\.svg$': string;
37
+ };
38
+ transformIgnorePatterns: string[];
39
+ };
40
+ /**
41
+ * Create custom Jest transformer with options
42
+ */
43
+ export declare function createJestTransformer(options?: JestPresetOptions): typeof svgerJestTransformer;
44
+ export default svgerJestTransformer;
@@ -0,0 +1,169 @@
1
+ /**
2
+ * Official Jest Preset for SVGER-CLI
3
+ *
4
+ * Provides Jest transformers and configuration for testing SVG components
5
+ * with full framework support.
6
+ *
7
+ * @example
8
+ * ```js
9
+ * // jest.config.js
10
+ * module.exports = {
11
+ * preset: 'svger-cli/jest',
12
+ * // or manually configure:
13
+ * transform: {
14
+ * '\\.svg$': 'svger-cli/jest-transformer'
15
+ * }
16
+ * };
17
+ * ```
18
+ */
19
+ import { svgProcessor } from '../processors/svg-processor.js';
20
+ import { configService } from '../services/config.js';
21
+ /**
22
+ * Jest transformer for SVG files
23
+ */
24
+ export const svgerJestTransformer = {
25
+ process(sourceText, sourcePath, options) {
26
+ const config = configService.readConfig();
27
+ const transformOptions = options?.transformerConfig?.svger || {};
28
+ // Check if we should mock instead of transform
29
+ if (transformOptions.mock) {
30
+ const componentName = svgProcessor.generateComponentName(sourcePath, 'pascal');
31
+ return {
32
+ code: `
33
+ const React = require('react');
34
+ const ${componentName} = (props) => React.createElement('svg', props);
35
+ module.exports = ${componentName};
36
+ module.exports.default = ${componentName};
37
+ `,
38
+ };
39
+ }
40
+ // Transform SVG to component
41
+ const framework = transformOptions.framework || config.framework || 'react';
42
+ const typescript = transformOptions.typescript !== undefined
43
+ ? transformOptions.typescript
44
+ : config.typescript;
45
+ const componentName = svgProcessor.generateComponentName(sourcePath, 'pascal');
46
+ try {
47
+ // Generate component synchronously for Jest
48
+ const component = generateComponentSync(componentName, sourceText, {
49
+ framework,
50
+ typescript,
51
+ defaultWidth: config.defaultWidth,
52
+ defaultHeight: config.defaultHeight,
53
+ defaultFill: config.defaultFill,
54
+ styleRules: config.styleRules || {},
55
+ });
56
+ // Convert to CommonJS for Jest
57
+ const commonJsCode = convertToCommonJS(component, componentName);
58
+ return {
59
+ code: commonJsCode,
60
+ };
61
+ }
62
+ catch (error) {
63
+ // Return a simple mock on error
64
+ return {
65
+ code: `
66
+ const React = require('react');
67
+ const ${componentName} = (props) => React.createElement('svg', props);
68
+ module.exports = ${componentName};
69
+ module.exports.default = ${componentName};
70
+ `,
71
+ };
72
+ }
73
+ },
74
+ };
75
+ /**
76
+ * Generate component synchronously (for Jest compatibility)
77
+ */
78
+ function generateComponentSync(componentName, svgContent, options) {
79
+ // Clean SVG content
80
+ const cleanedContent = svgProcessor.cleanSVGContent(svgContent);
81
+ // For Jest, we'll generate a simple React component
82
+ const viewBox = svgProcessor.extractViewBox(svgContent);
83
+ const template = `
84
+ import React from 'react';
85
+
86
+ interface ${componentName}Props {
87
+ width?: number | string;
88
+ height?: number | string;
89
+ fill?: string;
90
+ className?: string;
91
+ style?: React.CSSProperties;
92
+ }
93
+
94
+ const ${componentName}: React.FC<${componentName}Props> = ({
95
+ width = ${options.defaultWidth || 24},
96
+ height = ${options.defaultHeight || 24},
97
+ fill = '${options.defaultFill || 'currentColor'}',
98
+ className,
99
+ style,
100
+ ...props
101
+ }) => (
102
+ <svg
103
+ width={width}
104
+ height={height}
105
+ viewBox="${viewBox || '0 0 24 24'}"
106
+ fill={fill}
107
+ className={className}
108
+ style={style}
109
+ {...props}
110
+ >
111
+ ${cleanedContent}
112
+ </svg>
113
+ );
114
+
115
+ export default ${componentName};
116
+ `;
117
+ return template.trim();
118
+ }
119
+ /**
120
+ * Convert ES modules to CommonJS for Jest
121
+ */
122
+ function convertToCommonJS(code, componentName) {
123
+ // Simple conversion for Jest compatibility
124
+ let commonJsCode = code
125
+ .replace(/import\s+React\s+from\s+['"]react['"]/g, "const React = require('react')")
126
+ .replace(/export\s+default\s+/g, 'module.exports = ')
127
+ .replace(/export\s+{([^}]+)}/g, (match, exports) => {
128
+ const exportList = exports.split(',').map((e) => e.trim());
129
+ return exportList
130
+ .map((exp) => `module.exports.${exp} = ${exp}`)
131
+ .join(';');
132
+ });
133
+ // Ensure default export
134
+ if (!commonJsCode.includes('module.exports')) {
135
+ commonJsCode += `\nmodule.exports = ${componentName};`;
136
+ }
137
+ // Also add named export
138
+ commonJsCode += `\nmodule.exports.default = module.exports;`;
139
+ return commonJsCode;
140
+ }
141
+ /**
142
+ * Jest preset configuration
143
+ */
144
+ export const jestPreset = {
145
+ transform: {
146
+ '\\.svg$': ['svger-cli/jest-transformer', {}],
147
+ },
148
+ moduleNameMapper: {
149
+ '\\.svg$': 'svger-cli/jest-transformer',
150
+ },
151
+ transformIgnorePatterns: ['node_modules/(?!(svger-cli)/)'],
152
+ };
153
+ /**
154
+ * Create custom Jest transformer with options
155
+ */
156
+ export function createJestTransformer(options = {}) {
157
+ return {
158
+ process(sourceText, sourcePath, jestOptions) {
159
+ return svgerJestTransformer.process(sourceText, sourcePath, {
160
+ ...jestOptions,
161
+ transformerConfig: {
162
+ svger: options,
163
+ },
164
+ });
165
+ },
166
+ };
167
+ }
168
+ // Default exports
169
+ export default svgerJestTransformer;
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Official Next.js Plugin for SVGER-CLI
3
+ *
4
+ * Automatically converts SVG files to framework components in Next.js applications
5
+ * with full SSR support, HMR, and webpack integration.
6
+ *
7
+ * @example
8
+ * ```js
9
+ * // next.config.js
10
+ * const { withSvger } = require('svger-cli/nextjs');
11
+ *
12
+ * module.exports = withSvger({
13
+ * svger: {
14
+ * source: './src/icons',
15
+ * output: './src/components/icons',
16
+ * framework: 'react',
17
+ * typescript: true
18
+ * },
19
+ * // ... other Next.js config
20
+ * });
21
+ * ```
22
+ */
23
+ import { SvgerWebpackPlugin } from './webpack.js';
24
+ import type { NextJsPluginOptions } from '../types/integrations.js';
25
+ /**
26
+ * Next.js plugin configuration wrapper
27
+ */
28
+ export declare function withSvger(nextConfig?: any): any;
29
+ /**
30
+ * Standalone Next.js webpack plugin
31
+ * Can be used directly in next.config.js webpack function
32
+ */
33
+ export declare class SvgerNextJsPlugin extends SvgerWebpackPlugin {
34
+ constructor(options?: NextJsPluginOptions);
35
+ }
36
+ /**
37
+ * Helper function to configure SVG imports in Next.js
38
+ * For use in next.config.js
39
+ *
40
+ * @example
41
+ * ```js
42
+ * const { configureSvgImports } = require('svger-cli/nextjs');
43
+ *
44
+ * module.exports = {
45
+ * webpack(config, options) {
46
+ * configureSvgImports(config, {
47
+ * framework: 'react',
48
+ * typescript: true
49
+ * });
50
+ * return config;
51
+ * }
52
+ * };
53
+ * ```
54
+ */
55
+ export declare function configureSvgImports(webpackConfig: any, options?: Partial<NextJsPluginOptions>): void;
56
+ export default withSvger;