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/CHANGELOG.md +159 -0
- package/README.md +348 -15
- package/dist/index.d.ts +30 -0
- package/dist/index.js +33 -0
- package/dist/integrations/babel.d.ts +58 -0
- package/dist/integrations/babel.js +221 -0
- package/dist/integrations/jest-preset.d.ts +44 -0
- package/dist/integrations/jest-preset.js +169 -0
- package/dist/integrations/nextjs.d.ts +56 -0
- package/dist/integrations/nextjs.js +140 -0
- package/dist/integrations/rollup.d.ts +29 -0
- package/dist/integrations/rollup.js +197 -0
- package/dist/integrations/vite.d.ts +29 -0
- package/dist/integrations/vite.js +221 -0
- package/dist/integrations/webpack.d.ts +84 -0
- package/dist/integrations/webpack.js +273 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.js +2 -1
- package/dist/types/integrations.d.ts +255 -0
- package/dist/types/integrations.js +4 -0
- package/docs/INTEGRATION-IMPLEMENTATION-SUMMARY.md +448 -0
- package/docs/INTEGRATIONS.md +543 -0
- package/examples/babel.config.example.js +182 -0
- package/examples/jest.config.example.js +158 -0
- package/examples/next.config.example.js +133 -0
- package/examples/rollup.config.example.js +129 -0
- package/examples/vite.config.example.js +98 -0
- package/examples/webpack.config.example.js +88 -0
- package/package.json +74 -3
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;
|