svgfusion 1.5.0 → 1.6.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/README.md CHANGED
@@ -61,7 +61,7 @@ pnpm add svgfusion
61
61
 
62
62
  ## CLI Options
63
63
 
64
- <img src="https://i.ibb.co/8n2b5mtp/cli.png" alt="SVGFusion CLI" width="512" >
64
+ <img src="https://i.ibb.co/TD0QP5FC/cli.png" alt="SVGFusion CLI" width="512" >
65
65
 
66
66
  svgfusion ./icons --output ./components --prefix Icon --suffix Svg
67
67
 
package/dist/index.d.mts CHANGED
@@ -159,4 +159,50 @@ declare function sanitizeComponentName(name: string): string;
159
159
  */
160
160
  declare function formatComponentName(name: string, prefix?: string, suffix?: string): string;
161
161
 
162
- export { type BatchConversionOptions, type BatchConversionResult, type CliOptions, type ConversionError, type ConversionOptions, type ConversionResult, type Framework, type ReactConversionOptions, type VueConversionOptions, convertToReact, convertToVue, createSvgoConfig, formatComponentName, optimizeSvg, pascalCase, readSvgDirectory, readSvgFile, sanitizeComponentName, svgToComponentName, writeComponentFile, writeSvgFile };
162
+ interface IndexGenerationOptions {
163
+ format: 'ts' | 'js';
164
+ exportType: 'named' | 'default';
165
+ typescript: boolean;
166
+ }
167
+ /**
168
+ * Generate index file content for tree-shaking
169
+ */
170
+ declare function generateIndexFile(results: ConversionResult[], options: IndexGenerationOptions): string;
171
+
172
+ /**
173
+ * Batch converter for processing multiple SVG files
174
+ */
175
+ declare class BatchConverter {
176
+ private reactConverter;
177
+ private vueConverter;
178
+ /**
179
+ * Convert multiple SVG files to framework components
180
+ */
181
+ convertBatch(options: BatchConversionOptions): Promise<BatchConversionResult>;
182
+ /**
183
+ * Get component names from batch conversion results
184
+ */
185
+ getComponentNames(results: BatchConversionResult): string[];
186
+ /**
187
+ * Generate summary report of conversion results
188
+ */
189
+ generateSummaryReport(results: BatchConversionResult): string;
190
+ /**
191
+ * Get all SVG files in directory
192
+ */
193
+ private getSvgFiles;
194
+ /**
195
+ * Generate index file for tree-shaking
196
+ */
197
+ private generateIndexFile;
198
+ /**
199
+ * Get component name from file path
200
+ */
201
+ private getComponentNameFromFile;
202
+ /**
203
+ * Get output path for converted component
204
+ */
205
+ private getOutputPath;
206
+ }
207
+
208
+ export { type BatchConversionOptions, type BatchConversionResult, BatchConverter, type CliOptions, type ConversionError, type ConversionOptions, type ConversionResult, type Framework, type IndexGenerationOptions, type ReactConversionOptions, type VueConversionOptions, convertToReact, convertToVue, createSvgoConfig, formatComponentName, generateIndexFile, optimizeSvg, pascalCase, readSvgDirectory, readSvgFile, sanitizeComponentName, svgToComponentName, writeComponentFile, writeSvgFile };
package/dist/index.d.ts CHANGED
@@ -159,4 +159,50 @@ declare function sanitizeComponentName(name: string): string;
159
159
  */
160
160
  declare function formatComponentName(name: string, prefix?: string, suffix?: string): string;
161
161
 
162
- export { type BatchConversionOptions, type BatchConversionResult, type CliOptions, type ConversionError, type ConversionOptions, type ConversionResult, type Framework, type ReactConversionOptions, type VueConversionOptions, convertToReact, convertToVue, createSvgoConfig, formatComponentName, optimizeSvg, pascalCase, readSvgDirectory, readSvgFile, sanitizeComponentName, svgToComponentName, writeComponentFile, writeSvgFile };
162
+ interface IndexGenerationOptions {
163
+ format: 'ts' | 'js';
164
+ exportType: 'named' | 'default';
165
+ typescript: boolean;
166
+ }
167
+ /**
168
+ * Generate index file content for tree-shaking
169
+ */
170
+ declare function generateIndexFile(results: ConversionResult[], options: IndexGenerationOptions): string;
171
+
172
+ /**
173
+ * Batch converter for processing multiple SVG files
174
+ */
175
+ declare class BatchConverter {
176
+ private reactConverter;
177
+ private vueConverter;
178
+ /**
179
+ * Convert multiple SVG files to framework components
180
+ */
181
+ convertBatch(options: BatchConversionOptions): Promise<BatchConversionResult>;
182
+ /**
183
+ * Get component names from batch conversion results
184
+ */
185
+ getComponentNames(results: BatchConversionResult): string[];
186
+ /**
187
+ * Generate summary report of conversion results
188
+ */
189
+ generateSummaryReport(results: BatchConversionResult): string;
190
+ /**
191
+ * Get all SVG files in directory
192
+ */
193
+ private getSvgFiles;
194
+ /**
195
+ * Generate index file for tree-shaking
196
+ */
197
+ private generateIndexFile;
198
+ /**
199
+ * Get component name from file path
200
+ */
201
+ private getComponentNameFromFile;
202
+ /**
203
+ * Get output path for converted component
204
+ */
205
+ private getOutputPath;
206
+ }
207
+
208
+ export { type BatchConversionOptions, type BatchConversionResult, BatchConverter, type CliOptions, type ConversionError, type ConversionOptions, type ConversionResult, type Framework, type IndexGenerationOptions, type ReactConversionOptions, type VueConversionOptions, convertToReact, convertToVue, createSvgoConfig, formatComponentName, generateIndexFile, optimizeSvg, pascalCase, readSvgDirectory, readSvgFile, sanitizeComponentName, svgToComponentName, writeComponentFile, writeSvgFile };
package/dist/index.js CHANGED
@@ -1,20 +1,57 @@
1
- 'use strict';var promises=require('fs/promises'),path=require('path'),fs=require('fs'),core=require('@svgr/core'),svgo=require('svgo');var d=Object.defineProperty;var G=Object.getOwnPropertyDescriptor;var I=Object.getOwnPropertyNames;var k=Object.prototype.hasOwnProperty;var R=(e,r)=>()=>(e&&(r=e(e=0)),r);var q=(e,r)=>{for(var t in r)d(e,t,{get:r[t],enumerable:true});},Z=(e,r,t,o)=>{if(r&&typeof r=="object"||typeof r=="function")for(let n of I(r))!k.call(e,n)&&n!==t&&d(e,n,{get:()=>r[n],enumerable:!(o=G(r,n))||o.enumerable});return e};var _=e=>Z(d({},"__esModule",{value:true}),e);var i=R(()=>{});var D={};q(D,{ensureDir:()=>se,ensureDirectoryExists:()=>v,getComponentFilename:()=>ae,getFileExtension:()=>ie,readSvgDirectory:()=>x,readSvgFile:()=>O,writeComponentFile:()=>A,writeSvgFile:()=>P});async function O(e){try{return await promises.readFile(e,"utf-8")}catch(r){throw new Error(`Failed to read SVG file: ${e}. ${r}`)}}async function P(e,r){try{await v(path.dirname(e)),await promises.writeFile(e,r,"utf-8");}catch(t){throw new Error(`Failed to write SVG file: ${e}. ${t}`)}}async function A(e,r){try{await v(path.dirname(e)),await promises.writeFile(e,r,"utf-8");}catch(t){throw new Error(`Failed to write component file: ${e}. ${t}`)}}async function x(e,r=false){try{let t=await promises.readdir(e),o=[];for(let n of t){let s=path.join(e,n),a=await promises.stat(s);if(a.isDirectory()&&r){let m=await x(s,r);o.push(...m);}else a.isFile()&&path.extname(n).toLowerCase()===".svg"&&o.push(s);}return o}catch(t){throw new Error(`Failed to read directory: ${e}. ${t}`)}}async function v(e){fs.existsSync(e)||await promises.mkdir(e,{recursive:true});}function ie(e,r=true){return e==="react"?r?".tsx":".jsx":".vue"}function ae(e,r,t){return `${r}${t}`}var se,h=R(()=>{i();se=v;});i();i();i();i();var H={plugins:[{name:"preset-default",params:{overrides:{removeViewBox:false,removeTitle:false,removeDesc:false,removeUselessStrokeAndFill:false,convertColors:{currentColor:true,names2hex:true,rgb2hex:true,shorthex:true,shortname:true}}}},"removeDimensions","cleanupNumericValues"]};function C(e,r=H){try{return svgo.optimize(e,r).data}catch(t){throw new Error(`Failed to optimize SVG: ${t}`)}}function J(e){let r=[{name:"preset-default",params:{overrides:{removeViewBox:!e.removeViewBox,removeTitle:!e.removeTitle,removeDesc:!e.removeDesc,removeUselessStrokeAndFill:!e.preserveClasses,convertColors:e.preserveColors?false:{currentColor:true,names2hex:true,rgb2hex:true,shorthex:true,shortname:true}}}},"cleanupNumericValues"];return e.removeDimensions!==false&&r.push("removeDimensions"),{plugins:r}}i();i();var u=e=>e.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*[a-z]*|[A-Z]|[0-9]+[a-z]*/g)?.map(r=>r.charAt(0).toUpperCase()+r.slice(1).toLowerCase()).join("")||"";function K(e){let r=e.replace(/\.svg$/i,"");return r=Q(r),u(r)}function Q(e){let r=e.toLowerCase().replace(/[^a-zA-Z0-9]/g," ");return r=r.replace(/\s+/g," ").trim(),r}function W(e){return u(e.replace(/[^a-zA-Z0-9]/g," "))}function f(e,r,t){let o=r?u(r):"",n=t?u(t):"",s=u(e);return `${o}${s}${n}`}var g=class{async processSvg(r,t){let{optimize:o=true}=t;return o?C(r):r}generateComponentName(r){let{name:t,prefix:o,suffix:n}=r;return f(t||"Icon",o,n)}generateFilename(r,t,o=true){try{let{getFileExtension:n,getComponentFilename:s}=(h(),_(D)),a=n(t,o);return s("icon.svg",r,a)}catch{return `${r}${{react:o?".tsx":".jsx",vue:".vue"}[t]}`}}};i();function z(e){let{typescript:r=true,memo:t=true,ref:o=true,titleProp:n=true,descProp:s=true,icon:a=true,dimensions:m=false,replaceAttrValues:c={"#000":"currentColor","#000000":"currentColor"},svgProps:l={},expandProps:S=false,nativeProps:T=true,ariaLabelledBy:B=false,ariaHidden:L=false,role:j="img"}=e,b={typescript:r,memo:t,ref:o,titleProp:n,descProp:s,icon:a,dimensions:m,expandProps:S,svgProps:{className:"{className}",...o&&{ref:"{ref}"},...T&&{width:"{width}",height:"{height}",style:"{style}"},...B&&n&&s&&{"aria-labelledby":"{titleId} {descId}"},...L&&{"aria-hidden":"true"},role:j,...l},replaceAttrValues:c,plugins:["@svgr/plugin-svgo","@svgr/plugin-jsx","@svgr/plugin-prettier"]};return b.svgoConfig={plugins:[{name:"preset-default",params:{overrides:{removeViewBox:false,removeTitle:!n,removeDesc:!s,removeUselessStrokeAndFill:false,removeUnusedNS:false,removeUselessDefs:false,convertShapeToPath:false,mergePaths:false,convertColors:false}}},...a&&!m?[{name:"removeAttrs",params:{attrs:["width","height"]}}]:[],...a?["cleanupNumericValues"]:[]]},b}function U(e,r,t){let o=e;return w(o)&&(o=$(o,r)),o}function w(e){return ["linearGradient","radialGradient","pattern","mask","filter","clipPath","marker","symbol","use"].some(t=>e.includes(`<${t}`)||e.includes(`</${t}`))}function $(e,r){let t=`${r.toLowerCase()}_`;return e=e.replace(/id="([^"]+)"/g,`id="${t}$1"`),e=e.replace(/url\(#([^)]+)\)/g,`url(#${t}$1)`),e=e.replace(/href="#([^"]+)"/g,`href="#${t}$1"`),e}var y=class extends g{async convert(r,t={}){try{let o=this.generateComponentName(t),n=await this.processSvg(r,t);w(n)&&(n=$(n,o));let s=z(t),a=await core.transform(n,s,{componentName:o}),m=U(a,o,t),c=this.generateFilename(o,"react",t.typescript??!0);return {code:m,filename:c,componentName:o}}catch(o){throw new Error(`Failed to convert SVG to React: ${o}`)}}};async function le(e,r={}){return new y().convert(e,r)}i();i();function E(e,r){let{name:t,prefix:o,suffix:n,props:s=true,replaceAttrValues:a={"#000":"currentColor","#000000":"currentColor"}}=r,c=f(t||"Icon",o,n),l=pe(e);return l=me(l,a),ue(l)&&(l=ge(l,c)),l=fe(l,s),{code:ve(l,c,r),componentName:c}}function pe(e){return e.replace(/<\?xml[^>]*\?>\s*/,"").replace(/<!--[\s\S]*?-->/g,"").replace(/xmlns="[^"]*"/g,"").trim()}function me(e,r){let t=e;for(let[o,n]of Object.entries(r)){let s=new RegExp(o.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),"g");t=t.replace(s,n);}return t}function ue(e){return ["linearGradient","radialGradient","pattern","mask","filter","clipPath","marker","symbol","use"].some(t=>e.includes(`<${t}`)||e.includes(`</${t}`))}function ge(e,r){let t=`${r.toLowerCase()}_`;return e=e.replace(/id="([^"]+)"/g,`id="${t}$1"`),e=e.replace(/url\(#([^)]+)\)/g,`url(#${t}$1)`),e=e.replace(/href="#([^"]+)"/g,`href="#${t}$1"`),e}function fe(e,r){return r?e.replace("<svg",'<svg :class="className" :style="style" v-bind="$attrs"'):e}function ve(e,r,t){let{typescript:o,compositionApi:n,props:s}=t,c=`<script${o?' lang="ts"':""}${n?" setup":""}>`;n?s&&(c+=`
1
+ 'use strict';var promises=require('fs/promises'),path=require('path'),fs=require('fs'),core=require('@svgr/core'),svgo=require('svgo');var V=Object.defineProperty;var X=Object.getOwnPropertyDescriptor;var Y=Object.getOwnPropertyNames;var ee=Object.prototype.hasOwnProperty;var O=(e,t)=>()=>(e&&(t=e(e=0)),t);var z=(e,t)=>{for(var r in t)V(e,r,{get:t[r],enumerable:true});},te=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of Y(t))!ee.call(e,o)&&o!==r&&V(e,o,{get:()=>t[o],enumerable:!(n=X(t,o))||n.enumerable});return e};var re=e=>te(V({},"__esModule",{value:true}),e);var c=O(()=>{});var U={};z(U,{pascalCase:()=>exports.pascalCase});exports.pascalCase=void 0;var E=O(()=>{c();exports.pascalCase=e=>e.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*[a-z]*|[A-Z]|[0-9]+[a-z]*/g)?.map(t=>t.charAt(0).toUpperCase()+t.slice(1).toLowerCase()).join("")||"";});var T={};z(T,{ensureDir:()=>R,ensureDirectoryExists:()=>S,getComponentFilename:()=>Ce,getFileExtension:()=>de,readSvgDirectory:()=>D,readSvgFile:()=>q,writeComponentFile:()=>h,writeSvgFile:()=>Z});async function q(e){try{return await promises.readFile(e,"utf-8")}catch(t){throw new Error(`Failed to read SVG file: ${e}. ${t}`)}}async function Z(e,t){try{await S(path.dirname(e)),await promises.writeFile(e,t,"utf-8");}catch(r){throw new Error(`Failed to write SVG file: ${e}. ${r}`)}}async function h(e,t){try{await S(path.dirname(e)),await promises.writeFile(e,t,"utf-8");}catch(r){throw new Error(`Failed to write component file: ${e}. ${r}`)}}async function D(e,t=false){try{let r=await promises.readdir(e),n=[];for(let o of r){let s=path.join(e,o),i=await promises.stat(s);if(i.isDirectory()&&t){let a=await D(s,t);n.push(...a);}else i.isFile()&&path.extname(o).toLowerCase()===".svg"&&n.push(s);}return n}catch(r){throw new Error(`Failed to read directory: ${e}. ${r}`)}}async function S(e){fs.existsSync(e)||await promises.mkdir(e,{recursive:true});}function de(e,t=true){return e==="react"?t?".tsx":".jsx":".vue"}function Ce(e,t,r){return `${t}${r}`}var R,w=O(()=>{c();R=S;});c();c();c();c();var oe={plugins:[{name:"preset-default",params:{overrides:{removeViewBox:false,removeTitle:false,removeDesc:false,removeUselessStrokeAndFill:false,convertColors:{currentColor:true,names2hex:true,rgb2hex:true,shorthex:true,shortname:true}}}},"removeDimensions","cleanupNumericValues"]};function I(e,t=oe){try{return svgo.optimize(e,t).data}catch(r){throw new Error(`Failed to optimize SVG: ${r}`)}}function se(e){let t=[{name:"preset-default",params:{overrides:{removeViewBox:!e.removeViewBox,removeTitle:!e.removeTitle,removeDesc:!e.removeDesc,removeUselessStrokeAndFill:!e.preserveClasses,convertColors:e.preserveColors?false:{currentColor:true,names2hex:true,rgb2hex:true,shorthex:true,shortname:true}}}},"cleanupNumericValues"];return e.removeDimensions!==false&&t.push("removeDimensions"),{plugins:t}}c();E();function ie(e){let t=e.replace(/\.svg$/i,"");return t=ae(t),exports.pascalCase(t)}function ae(e){let t=e.toLowerCase().replace(/[^a-zA-Z0-9]/g," ");return t=t.replace(/\s+/g," ").trim(),t}function ce(e){return exports.pascalCase(e.replace(/[^a-zA-Z0-9]/g," "))}function x(e,t,r){let n=t?exports.pascalCase(t):"",o=r?exports.pascalCase(r):"",s=exports.pascalCase(e);return `${n}${s}${o}`}var C=class{async processSvg(t,r){let{optimize:n=true}=r;return n?I(t):t}generateComponentName(t){let{name:r,prefix:n,suffix:o}=t;return x(r||"Icon",n,o)}generateFilename(t,r,n=true){try{let{getFileExtension:o,getComponentFilename:s}=(w(),re(T)),i=o(r,n);return s("icon.svg",t,i)}catch{return `${t}${{react:n?".tsx":".jsx",vue:".vue"}[r]}`}}};c();function M(e){let{typescript:t=true,memo:r=true,ref:n=true,titleProp:o=true,descProp:s=true,icon:i=true,dimensions:a=false,replaceAttrValues:l={"#000":"currentColor","#000000":"currentColor"},svgProps:p={},expandProps:v=false,nativeProps:f=true,ariaLabelledBy:d=false,ariaHidden:u=false,role:b="img"}=e,F={typescript:t,memo:r,ref:n,titleProp:o,descProp:s,icon:i,dimensions:a,expandProps:v,svgProps:{className:"{className}",...n&&{ref:"{ref}"},...f&&{width:"{width}",height:"{height}",style:"{style}"},...d&&o&&s&&{"aria-labelledby":"{titleId} {descId}"},...u&&{"aria-hidden":"true"},role:b,...p},replaceAttrValues:l,plugins:["@svgr/plugin-svgo","@svgr/plugin-jsx","@svgr/plugin-prettier"]};return F.svgoConfig={plugins:[{name:"preset-default",params:{overrides:{removeViewBox:false,removeTitle:!o,removeDesc:!s,removeUselessStrokeAndFill:false,removeUnusedNS:false,removeUselessDefs:false,convertShapeToPath:false,mergePaths:false,convertColors:false}}},...i&&!a?[{name:"removeAttrs",params:{attrs:["width","height"]}}]:[],...i?["cleanupNumericValues"]:[]]},F}function W(e,t,r){let n=e;return B(n)&&(n=A(n,t)),n}function B(e){return ["linearGradient","radialGradient","pattern","mask","filter","clipPath","marker","symbol","use"].some(r=>e.includes(`<${r}`)||e.includes(`</${r}`))}function A(e,t){let r=`${t.toLowerCase()}_`;return e=e.replace(/id="([^"]+)"/g,`id="${r}$1"`),e=e.replace(/url\(#([^)]+)\)/g,`url(#${r}$1)`),e=e.replace(/href="#([^"]+)"/g,`href="#${r}$1"`),e}var y=class extends C{async convert(t,r={}){try{let n=this.generateComponentName(r),o=await this.processSvg(t,r);B(o)&&(o=A(o,n));let s=M(r),i=await core.transform(o,s,{componentName:n}),a=W(i,n,r),l=this.generateFilename(n,"react",r.typescript??!0);return {code:a,filename:l,componentName:n}}catch(n){throw new Error(`Failed to convert SVG to React: ${n}`)}}};async function he(e,t={}){return new y().convert(e,t)}c();c();function H(e,t){let{name:r,prefix:n,suffix:o,props:s=true,replaceAttrValues:i={"#000":"currentColor","#000000":"currentColor"}}=t,l=x(r||"Icon",n,o),p=we(e);return p=ye(p,i),$e(p)&&(p=Fe(p,l)),p=Se(p,s),{code:Re(p,l,t),componentName:l}}function we(e){return e.replace(/<\?xml[^>]*\?>\s*/,"").replace(/<!--[\s\S]*?-->/g,"").replace(/xmlns="[^"]*"/g,"").trim()}function ye(e,t){let r=e;for(let[n,o]of Object.entries(t)){let s=new RegExp(n.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),"g");r=r.replace(s,o);}return r}function $e(e){return ["linearGradient","radialGradient","pattern","mask","filter","clipPath","marker","symbol","use"].some(r=>e.includes(`<${r}`)||e.includes(`</${r}`))}function Fe(e,t){let r=`${t.toLowerCase()}_`;return e=e.replace(/id="([^"]+)"/g,`id="${r}$1"`),e=e.replace(/url\(#([^)]+)\)/g,`url(#${r}$1)`),e=e.replace(/href="#([^"]+)"/g,`href="#${r}$1"`),e}function Se(e,t){return t?e.replace("<svg",'<svg :class="className" :style="style" v-bind="$attrs"'):e}function Re(e,t,r){let{typescript:n,compositionApi:o,props:s}=r,l=`<script${n?' lang="ts"':""}${o?" setup":""}>`;o?s&&(l+=`
2
2
  interface Props {
3
3
  className?: string;
4
4
  style?: Record<string, any>;
5
5
  }
6
6
 
7
7
  defineProps<Props>();
8
- `):c+=`
8
+ `):l+=`
9
9
  export default {
10
- name: '${r}',
10
+ name: '${t}',
11
11
  props: {
12
12
  className: String,
13
13
  style: Object,
14
14
  },
15
15
  };
16
- `,c+="</script>";let l=`
16
+ `,l+="</script>";let p=`
17
17
  <template>
18
18
  ${e}
19
- </template>`;return [c,l].filter(Boolean).join(`
20
- `)}var F=class extends g{async convert(r,t={}){try{let o=await this.processSvg(r,t),{code:n,componentName:s}=E(o,t),a=this.generateFilename(s,"vue",t.typescript??!0);return {code:n,filename:a,componentName:s}}catch(o){throw new Error(`Failed to convert SVG to Vue: ${o}`)}}};async function de(e,r={}){return new F().convert(e,r)}h();exports.convertToReact=le;exports.convertToVue=de;exports.createSvgoConfig=J;exports.formatComponentName=f;exports.optimizeSvg=C;exports.pascalCase=u;exports.readSvgDirectory=x;exports.readSvgFile=O;exports.sanitizeComponentName=W;exports.svgToComponentName=K;exports.writeComponentFile=A;exports.writeSvgFile=P;
19
+ </template>`;return [l,p].filter(Boolean).join(`
20
+ `)}var $=class extends C{async convert(t,r={}){try{let n=await this.processSvg(t,r),{code:o,componentName:s}=H(n,r),i=this.generateFilename(s,"vue",r.typescript??!0);return {code:o,filename:i,componentName:s}}catch(n){throw new Error(`Failed to convert SVG to Vue: ${n}`)}}};async function Ne(e,t={}){return new $().convert(e,t)}w();c();function k(e,t){let{format:r,exportType:n,typescript:o}=t,s=[...e].sort((i,a)=>i.componentName.localeCompare(a.componentName));return n==="default"?Pe(s):be(s,r,o)}function be(e,t,r){let n="";n+=`// Auto-generated index file for tree-shaking
21
+ `,n+=`// This file exports all components for optimal bundling
22
+
23
+ `;for(let o of e){let s=G(o.filename);n+=`export { default as ${o.componentName} } from './${s}';
24
+ `;}n+=`
25
+ // Barrel export for convenience
26
+ `,n+=`export {
27
+ `;for(let o of e)n+=` ${o.componentName},
28
+ `;if(n+=`};
29
+ `,r&&t==="ts"){n+=`
30
+ // TypeScript component types
31
+ `,n+=`export type IconComponent = React.ComponentType<React.SVGProps<SVGSVGElement>>;
32
+ `,n+=`export type IconComponents = {
33
+ `;for(let o of e)n+=` ${o.componentName}: IconComponent;
34
+ `;n+=`};
35
+ `;}return n}function Pe(e,t,r){let n="";n+=`// Auto-generated index file
36
+ `,n+=`// Warning: Default exports are less tree-shakeable
37
+
38
+ `;for(let o of e){let s=G(o.filename);n+=`import ${o.componentName} from './${s}';
39
+ `;}n+=`
40
+ export default {
41
+ `;for(let o of e)n+=` ${o.componentName},
42
+ `;n+=`};
43
+ `,n+=`
44
+ // Individual exports for flexibility
45
+ `;for(let o of e)n+=`export { default as ${o.componentName} } from './${G(o.filename)}';
46
+ `;return n}function G(e){return e.replace(/\.(tsx?|jsx?|vue)$/,"")}c();w();var j=class{reactConverter=new y;vueConverter=new $;async convertBatch(t){let{inputDir:r,outputDir:n,recursive:o=false,extensions:s=[".svg"],generateIndex:i=false,framework:a="react",...l}=t,p=[],v=[];try{await R(n);let f=await this.getSvgFiles(r,o,s);for(let d of f)try{let{readSvgFile:u}=await Promise.resolve().then(()=>(w(),T)),b=await u(d),F=a==="react"?this.reactConverter:this.vueConverter,K=await this.getComponentNameFromFile(d,t),P=await F.convert(b,{...l,name:K}),Q=await this.getOutputPath(d,r,n,P.filename);await h(Q,P.code),p.push(P);}catch(u){v.push({file:d,error:u instanceof Error?u.message:String(u),stack:u instanceof Error?u.stack:void 0});}return i&&p.length>0&&await this.generateIndexFile(n,p,t),{results:p,errors:v,summary:{total:f.length,successful:p.length,failed:v.length}}}catch(f){throw new Error(`Batch conversion failed: ${f instanceof Error?f.message:String(f)}`)}}getComponentNames(t){return t.results.map(r=>r.componentName)}generateSummaryReport(t){let{summary:r,errors:n}=t,o=this.getComponentNames(t),s=`
47
+ === SVG Conversion Summary ===
48
+ `;return s+=`Total files processed: ${r.total}
49
+ `,s+=`Successful conversions: ${r.successful}
50
+ `,s+=`Failed conversions: ${r.failed}
51
+ `,o.length>0&&(s+=`
52
+ Generated components:
53
+ `,o.forEach(i=>{s+=` - ${i}
54
+ `;})),n.length>0&&(s+=`
55
+ Errors:
56
+ `,n.forEach(i=>{s+=` - ${i.file}: ${i.error}
57
+ `;})),s}async getSvgFiles(t,r,n){let o=[],s=await promises.readdir(t);for(let i of s){let a=path.join(t,i),l=await promises.stat(a);if(l.isDirectory()&&r){let p=await this.getSvgFiles(a,r,n);o.push(...p);}else l.isFile()&&n.includes(path.extname(i).toLowerCase())&&o.push(a);}return o}async generateIndexFile(t,r,n){let{indexFormat:o="ts",exportType:s="named",typescript:i=true}=n,a=k(r,{format:o,exportType:s,typescript:i}),l=`index.${o}`,p=path.join(t,l);await h(p,a);}async getComponentNameFromFile(t,r){let n=path.basename(t,path.extname(t)),{prefix:o="",suffix:s=""}=r,{pascalCase:i}=await Promise.resolve().then(()=>(E(),U)),a=i(n);return o&&(a=`${i(o)}${a}`),s&&(a=`${a}${i(s)}`),a}async getOutputPath(t,r,n,o){let s=t.replace(r,"").replace(/^[/\\]/,""),i=s.includes("/")?s.substring(0,s.lastIndexOf("/")):s.includes("\\")?s.substring(0,s.lastIndexOf("\\")):"",a=i?path.join(n,i,o):path.join(n,o);return await R(path.dirname(a)),a}};exports.BatchConverter=j;exports.convertToReact=he;exports.convertToVue=Ne;exports.createSvgoConfig=se;exports.formatComponentName=x;exports.generateIndexFile=k;exports.optimizeSvg=I;exports.readSvgDirectory=D;exports.readSvgFile=q;exports.sanitizeComponentName=ce;exports.svgToComponentName=ie;exports.writeComponentFile=h;exports.writeSvgFile=Z;
package/dist/index.mjs CHANGED
@@ -1,20 +1,57 @@
1
- import {dirname,join,extname}from'path';import'url';import {readFile,writeFile,readdir,stat,mkdir}from'fs/promises';import {existsSync}from'fs';import {transform}from'@svgr/core';import {optimize}from'svgo';var d=Object.defineProperty;var k=Object.getOwnPropertyDescriptor;var _=Object.getOwnPropertyNames;var I=Object.prototype.hasOwnProperty;var N=(e,r)=>()=>(e&&(r=e(e=0)),r);var q=(e,r)=>{for(var t in r)d(e,t,{get:r[t],enumerable:true});},Z=(e,r,t,o)=>{if(r&&typeof r=="object"||typeof r=="function")for(let n of _(r))!I.call(e,n)&&n!==t&&d(e,n,{get:()=>r[n],enumerable:!(o=k(r,n))||o.enumerable});return e};var H=e=>Z(d({},"__esModule",{value:true}),e);var i=N(()=>{});var z={};q(z,{ensureDir:()=>ie,ensureDirectoryExists:()=>C,getComponentFilename:()=>ce,getFileExtension:()=>ae,readSvgDirectory:()=>h,readSvgFile:()=>O,writeComponentFile:()=>D,writeSvgFile:()=>A});async function O(e){try{return await readFile(e,"utf-8")}catch(r){throw new Error(`Failed to read SVG file: ${e}. ${r}`)}}async function A(e,r){try{await C(dirname(e)),await writeFile(e,r,"utf-8");}catch(t){throw new Error(`Failed to write SVG file: ${e}. ${t}`)}}async function D(e,r){try{await C(dirname(e)),await writeFile(e,r,"utf-8");}catch(t){throw new Error(`Failed to write component file: ${e}. ${t}`)}}async function h(e,r=false){try{let t=await readdir(e),o=[];for(let n of t){let s=join(e,n),a=await stat(s);if(a.isDirectory()&&r){let u=await h(s,r);o.push(...u);}else a.isFile()&&extname(n).toLowerCase()===".svg"&&o.push(s);}return o}catch(t){throw new Error(`Failed to read directory: ${e}. ${t}`)}}async function C(e){existsSync(e)||await mkdir(e,{recursive:true});}function ae(e,r=true){return e==="react"?r?".tsx":".jsx":".vue"}function ce(e,r,t){return `${r}${t}`}var ie,w=N(()=>{i();ie=C;});i();i();i();i();var K={plugins:[{name:"preset-default",params:{overrides:{removeViewBox:false,removeTitle:false,removeDesc:false,removeUselessStrokeAndFill:false,convertColors:{currentColor:true,names2hex:true,rgb2hex:true,shorthex:true,shortname:true}}}},"removeDimensions","cleanupNumericValues"]};function x(e,r=K){try{return optimize(e,r).data}catch(t){throw new Error(`Failed to optimize SVG: ${t}`)}}function M(e){let r=[{name:"preset-default",params:{overrides:{removeViewBox:!e.removeViewBox,removeTitle:!e.removeTitle,removeDesc:!e.removeDesc,removeUselessStrokeAndFill:!e.preserveClasses,convertColors:e.preserveColors?false:{currentColor:true,names2hex:true,rgb2hex:true,shorthex:true,shortname:true}}}},"cleanupNumericValues"];return e.removeDimensions!==false&&r.push("removeDimensions"),{plugins:r}}i();i();var g=e=>e.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*[a-z]*|[A-Z]|[0-9]+[a-z]*/g)?.map(r=>r.charAt(0).toUpperCase()+r.slice(1).toLowerCase()).join("")||"";function Q(e){let r=e.replace(/\.svg$/i,"");return r=W(r),g(r)}function W(e){let r=e.toLowerCase().replace(/[^a-zA-Z0-9]/g," ");return r=r.replace(/\s+/g," ").trim(),r}function X(e){return g(e.replace(/[^a-zA-Z0-9]/g," "))}function v(e,r,t){let o=r?g(r):"",n=t?g(t):"",s=g(e);return `${o}${s}${n}`}var f=class{async processSvg(r,t){let{optimize:o=true}=t;return o?x(r):r}generateComponentName(r){let{name:t,prefix:o,suffix:n}=r;return v(t||"Icon",o,n)}generateFilename(r,t,o=true){try{let{getFileExtension:n,getComponentFilename:s}=(w(),H(z)),a=n(t,o);return s("icon.svg",r,a)}catch{return `${r}${{react:o?".tsx":".jsx",vue:".vue"}[t]}`}}};i();function T(e){let{typescript:r=true,memo:t=true,ref:o=true,titleProp:n=true,descProp:s=true,icon:a=true,dimensions:u=false,replaceAttrValues:c={"#000":"currentColor","#000000":"currentColor"},svgProps:l={},expandProps:b=false,nativeProps:U=true,ariaLabelledBy:G=false,ariaHidden:L=false,role:j="img"}=e,V={typescript:r,memo:t,ref:o,titleProp:n,descProp:s,icon:a,dimensions:u,expandProps:b,svgProps:{className:"{className}",...o&&{ref:"{ref}"},...U&&{width:"{width}",height:"{height}",style:"{style}"},...G&&n&&s&&{"aria-labelledby":"{titleId} {descId}"},...L&&{"aria-hidden":"true"},role:j,...l},replaceAttrValues:c,plugins:["@svgr/plugin-svgo","@svgr/plugin-jsx","@svgr/plugin-prettier"]};return V.svgoConfig={plugins:[{name:"preset-default",params:{overrides:{removeViewBox:false,removeTitle:!n,removeDesc:!s,removeUselessStrokeAndFill:false,removeUnusedNS:false,removeUselessDefs:false,convertShapeToPath:false,mergePaths:false,convertColors:false}}},...a&&!u?[{name:"removeAttrs",params:{attrs:["width","height"]}}]:[],...a?["cleanupNumericValues"]:[]]},V}function E(e,r,t){let o=e;return $(o)&&(o=y(o,r)),o}function $(e){return ["linearGradient","radialGradient","pattern","mask","filter","clipPath","marker","symbol","use"].some(t=>e.includes(`<${t}`)||e.includes(`</${t}`))}function y(e,r){let t=`${r.toLowerCase()}_`;return e=e.replace(/id="([^"]+)"/g,`id="${t}$1"`),e=e.replace(/url\(#([^)]+)\)/g,`url(#${t}$1)`),e=e.replace(/href="#([^"]+)"/g,`href="#${t}$1"`),e}var F=class extends f{async convert(r,t={}){try{let o=this.generateComponentName(t),n=await this.processSvg(r,t);$(n)&&(n=y(n,o));let s=T(t),a=await transform(n,s,{componentName:o}),u=E(a,o,t),c=this.generateFilename(o,"react",t.typescript??!0);return {code:u,filename:c,componentName:o}}catch(o){throw new Error(`Failed to convert SVG to React: ${o}`)}}};async function pe(e,r={}){return new F().convert(e,r)}i();i();function B(e,r){let{name:t,prefix:o,suffix:n,props:s=true,replaceAttrValues:a={"#000":"currentColor","#000000":"currentColor"}}=r,c=v(t||"Icon",o,n),l=me(e);return l=ue(l,a),ge(l)&&(l=fe(l,c)),l=ve(l,s),{code:Ce(l,c,r),componentName:c}}function me(e){return e.replace(/<\?xml[^>]*\?>\s*/,"").replace(/<!--[\s\S]*?-->/g,"").replace(/xmlns="[^"]*"/g,"").trim()}function ue(e,r){let t=e;for(let[o,n]of Object.entries(r)){let s=new RegExp(o.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),"g");t=t.replace(s,n);}return t}function ge(e){return ["linearGradient","radialGradient","pattern","mask","filter","clipPath","marker","symbol","use"].some(t=>e.includes(`<${t}`)||e.includes(`</${t}`))}function fe(e,r){let t=`${r.toLowerCase()}_`;return e=e.replace(/id="([^"]+)"/g,`id="${t}$1"`),e=e.replace(/url\(#([^)]+)\)/g,`url(#${t}$1)`),e=e.replace(/href="#([^"]+)"/g,`href="#${t}$1"`),e}function ve(e,r){return r?e.replace("<svg",'<svg :class="className" :style="style" v-bind="$attrs"'):e}function Ce(e,r,t){let{typescript:o,compositionApi:n,props:s}=t,c=`<script${o?' lang="ts"':""}${n?" setup":""}>`;n?s&&(c+=`
1
+ import {dirname,join,extname,basename}from'path';import'url';import {readFile,writeFile,readdir,stat,mkdir}from'fs/promises';import {existsSync}from'fs';import {transform}from'@svgr/core';import {optimize}from'svgo';var O=Object.defineProperty;var Y=Object.getOwnPropertyDescriptor;var ee=Object.getOwnPropertyNames;var te=Object.prototype.hasOwnProperty;var E=(e,t)=>()=>(e&&(t=e(e=0)),t);var U=(e,t)=>{for(var r in t)O(e,r,{get:t[r],enumerable:true});},re=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of ee(t))!te.call(e,o)&&o!==r&&O(e,o,{get:()=>t[o],enumerable:!(n=Y(t,o))||n.enumerable});return e};var ne=e=>re(O({},"__esModule",{value:true}),e);var c=E(()=>{});var L={};U(L,{pascalCase:()=>v});var v,D=E(()=>{c();v=e=>e.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*[a-z]*|[A-Z]|[0-9]+[a-z]*/g)?.map(t=>t.charAt(0).toUpperCase()+t.slice(1).toLowerCase()).join("")||"";});var B={};U(B,{ensureDir:()=>R,ensureDirectoryExists:()=>N,getComponentFilename:()=>xe,getFileExtension:()=>Ce,readSvgDirectory:()=>T,readSvgFile:()=>Z,writeComponentFile:()=>w,writeSvgFile:()=>W});async function Z(e){try{return await readFile(e,"utf-8")}catch(t){throw new Error(`Failed to read SVG file: ${e}. ${t}`)}}async function W(e,t){try{await N(dirname(e)),await writeFile(e,t,"utf-8");}catch(r){throw new Error(`Failed to write SVG file: ${e}. ${r}`)}}async function w(e,t){try{await N(dirname(e)),await writeFile(e,t,"utf-8");}catch(r){throw new Error(`Failed to write component file: ${e}. ${r}`)}}async function T(e,t=false){try{let r=await readdir(e),n=[];for(let o of r){let s=join(e,o),i=await stat(s);if(i.isDirectory()&&t){let a=await T(s,t);n.push(...a);}else i.isFile()&&extname(o).toLowerCase()===".svg"&&n.push(s);}return n}catch(r){throw new Error(`Failed to read directory: ${e}. ${r}`)}}async function N(e){existsSync(e)||await mkdir(e,{recursive:true});}function Ce(e,t=true){return e==="react"?t?".tsx":".jsx":".vue"}function xe(e,t,r){return `${t}${r}`}var R,y=E(()=>{c();R=N;});c();c();c();c();var se={plugins:[{name:"preset-default",params:{overrides:{removeViewBox:false,removeTitle:false,removeDesc:false,removeUselessStrokeAndFill:false,convertColors:{currentColor:true,names2hex:true,rgb2hex:true,shorthex:true,shortname:true}}}},"removeDimensions","cleanupNumericValues"]};function I(e,t=se){try{return optimize(e,t).data}catch(r){throw new Error(`Failed to optimize SVG: ${r}`)}}function ie(e){let t=[{name:"preset-default",params:{overrides:{removeViewBox:!e.removeViewBox,removeTitle:!e.removeTitle,removeDesc:!e.removeDesc,removeUselessStrokeAndFill:!e.preserveClasses,convertColors:e.preserveColors?false:{currentColor:true,names2hex:true,rgb2hex:true,shorthex:true,shortname:true}}}},"cleanupNumericValues"];return e.removeDimensions!==false&&t.push("removeDimensions"),{plugins:t}}c();D();function ae(e){let t=e.replace(/\.svg$/i,"");return t=ce(t),v(t)}function ce(e){let t=e.toLowerCase().replace(/[^a-zA-Z0-9]/g," ");return t=t.replace(/\s+/g," ").trim(),t}function pe(e){return v(e.replace(/[^a-zA-Z0-9]/g," "))}function h(e,t,r){let n=t?v(t):"",o=r?v(r):"",s=v(e);return `${n}${s}${o}`}var x=class{async processSvg(t,r){let{optimize:n=true}=r;return n?I(t):t}generateComponentName(t){let{name:r,prefix:n,suffix:o}=t;return h(r||"Icon",n,o)}generateFilename(t,r,n=true){try{let{getFileExtension:o,getComponentFilename:s}=(y(),ne(B)),i=o(r,n);return s("icon.svg",t,i)}catch{return `${t}${{react:n?".tsx":".jsx",vue:".vue"}[r]}`}}};c();function H(e){let{typescript:t=true,memo:r=true,ref:n=true,titleProp:o=true,descProp:s=true,icon:i=true,dimensions:a=false,replaceAttrValues:m={"#000":"currentColor","#000000":"currentColor"},svgProps:p={},expandProps:d=false,nativeProps:g=true,ariaLabelledBy:C=false,ariaHidden:f=false,role:P="img"}=e,S={typescript:t,memo:r,ref:n,titleProp:o,descProp:s,icon:i,dimensions:a,expandProps:d,svgProps:{className:"{className}",...n&&{ref:"{ref}"},...g&&{width:"{width}",height:"{height}",style:"{style}"},...C&&o&&s&&{"aria-labelledby":"{titleId} {descId}"},...f&&{"aria-hidden":"true"},role:P,...p},replaceAttrValues:m,plugins:["@svgr/plugin-svgo","@svgr/plugin-jsx","@svgr/plugin-prettier"]};return S.svgoConfig={plugins:[{name:"preset-default",params:{overrides:{removeViewBox:false,removeTitle:!o,removeDesc:!s,removeUselessStrokeAndFill:false,removeUnusedNS:false,removeUselessDefs:false,convertShapeToPath:false,mergePaths:false,convertColors:false}}},...i&&!a?[{name:"removeAttrs",params:{attrs:["width","height"]}}]:[],...i?["cleanupNumericValues"]:[]]},S}function J(e,t,r){let n=e;return A(n)&&(n=G(n,t)),n}function A(e){return ["linearGradient","radialGradient","pattern","mask","filter","clipPath","marker","symbol","use"].some(r=>e.includes(`<${r}`)||e.includes(`</${r}`))}function G(e,t){let r=`${t.toLowerCase()}_`;return e=e.replace(/id="([^"]+)"/g,`id="${r}$1"`),e=e.replace(/url\(#([^)]+)\)/g,`url(#${r}$1)`),e=e.replace(/href="#([^"]+)"/g,`href="#${r}$1"`),e}var $=class extends x{async convert(t,r={}){try{let n=this.generateComponentName(r),o=await this.processSvg(t,r);A(o)&&(o=G(o,n));let s=H(r),i=await transform(o,s,{componentName:n}),a=J(i,n,r),m=this.generateFilename(n,"react",r.typescript??!0);return {code:a,filename:m,componentName:n}}catch(n){throw new Error(`Failed to convert SVG to React: ${n}`)}}};async function we(e,t={}){return new $().convert(e,t)}c();c();function K(e,t){let{name:r,prefix:n,suffix:o,props:s=true,replaceAttrValues:i={"#000":"currentColor","#000000":"currentColor"}}=t,m=h(r||"Icon",n,o),p=ye(e);return p=$e(p,i),Fe(p)&&(p=Se(p,m)),p=Ne(p,s),{code:Re(p,m,t),componentName:m}}function ye(e){return e.replace(/<\?xml[^>]*\?>\s*/,"").replace(/<!--[\s\S]*?-->/g,"").replace(/xmlns="[^"]*"/g,"").trim()}function $e(e,t){let r=e;for(let[n,o]of Object.entries(t)){let s=new RegExp(n.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),"g");r=r.replace(s,o);}return r}function Fe(e){return ["linearGradient","radialGradient","pattern","mask","filter","clipPath","marker","symbol","use"].some(r=>e.includes(`<${r}`)||e.includes(`</${r}`))}function Se(e,t){let r=`${t.toLowerCase()}_`;return e=e.replace(/id="([^"]+)"/g,`id="${r}$1"`),e=e.replace(/url\(#([^)]+)\)/g,`url(#${r}$1)`),e=e.replace(/href="#([^"]+)"/g,`href="#${r}$1"`),e}function Ne(e,t){return t?e.replace("<svg",'<svg :class="className" :style="style" v-bind="$attrs"'):e}function Re(e,t,r){let{typescript:n,compositionApi:o,props:s}=r,m=`<script${n?' lang="ts"':""}${o?" setup":""}>`;o?s&&(m+=`
2
2
  interface Props {
3
3
  className?: string;
4
4
  style?: Record<string, any>;
5
5
  }
6
6
 
7
7
  defineProps<Props>();
8
- `):c+=`
8
+ `):m+=`
9
9
  export default {
10
- name: '${r}',
10
+ name: '${t}',
11
11
  props: {
12
12
  className: String,
13
13
  style: Object,
14
14
  },
15
15
  };
16
- `,c+="</script>";let l=`
16
+ `,m+="</script>";let p=`
17
17
  <template>
18
18
  ${e}
19
- </template>`;return [c,l].filter(Boolean).join(`
20
- `)}var S=class extends f{async convert(r,t={}){try{let o=await this.processSvg(r,t),{code:n,componentName:s}=B(o,t),a=this.generateFilename(s,"vue",t.typescript??!0);return {code:n,filename:a,componentName:s}}catch(o){throw new Error(`Failed to convert SVG to Vue: ${o}`)}}};async function de(e,r={}){return new S().convert(e,r)}w();export{pe as convertToReact,de as convertToVue,M as createSvgoConfig,v as formatComponentName,x as optimizeSvg,g as pascalCase,h as readSvgDirectory,O as readSvgFile,X as sanitizeComponentName,Q as svgToComponentName,D as writeComponentFile,A as writeSvgFile};
19
+ </template>`;return [m,p].filter(Boolean).join(`
20
+ `)}var F=class extends x{async convert(t,r={}){try{let n=await this.processSvg(t,r),{code:o,componentName:s}=K(n,r),i=this.generateFilename(s,"vue",r.typescript??!0);return {code:o,filename:i,componentName:s}}catch(n){throw new Error(`Failed to convert SVG to Vue: ${n}`)}}};async function be(e,t={}){return new F().convert(e,t)}y();c();function z(e,t){let{format:r,exportType:n,typescript:o}=t,s=[...e].sort((i,a)=>i.componentName.localeCompare(a.componentName));return n==="default"?Ve(s):Pe(s,r,o)}function Pe(e,t,r){let n="";n+=`// Auto-generated index file for tree-shaking
21
+ `,n+=`// This file exports all components for optimal bundling
22
+
23
+ `;for(let o of e){let s=k(o.filename);n+=`export { default as ${o.componentName} } from './${s}';
24
+ `;}n+=`
25
+ // Barrel export for convenience
26
+ `,n+=`export {
27
+ `;for(let o of e)n+=` ${o.componentName},
28
+ `;if(n+=`};
29
+ `,r&&t==="ts"){n+=`
30
+ // TypeScript component types
31
+ `,n+=`export type IconComponent = React.ComponentType<React.SVGProps<SVGSVGElement>>;
32
+ `,n+=`export type IconComponents = {
33
+ `;for(let o of e)n+=` ${o.componentName}: IconComponent;
34
+ `;n+=`};
35
+ `;}return n}function Ve(e,t,r){let n="";n+=`// Auto-generated index file
36
+ `,n+=`// Warning: Default exports are less tree-shakeable
37
+
38
+ `;for(let o of e){let s=k(o.filename);n+=`import ${o.componentName} from './${s}';
39
+ `;}n+=`
40
+ export default {
41
+ `;for(let o of e)n+=` ${o.componentName},
42
+ `;n+=`};
43
+ `,n+=`
44
+ // Individual exports for flexibility
45
+ `;for(let o of e)n+=`export { default as ${o.componentName} } from './${k(o.filename)}';
46
+ `;return n}function k(e){return e.replace(/\.(tsx?|jsx?|vue)$/,"")}c();y();var j=class{reactConverter=new $;vueConverter=new F;async convertBatch(t){let{inputDir:r,outputDir:n,recursive:o=false,extensions:s=[".svg"],generateIndex:i=false,framework:a="react",...m}=t,p=[],d=[];try{await R(n);let g=await this.getSvgFiles(r,o,s);for(let C of g)try{let{readSvgFile:f}=await Promise.resolve().then(()=>(y(),B)),P=await f(C),S=a==="react"?this.reactConverter:this.vueConverter,Q=await this.getComponentNameFromFile(C,t),V=await S.convert(P,{...m,name:Q}),X=await this.getOutputPath(C,r,n,V.filename);await w(X,V.code),p.push(V);}catch(f){d.push({file:C,error:f instanceof Error?f.message:String(f),stack:f instanceof Error?f.stack:void 0});}return i&&p.length>0&&await this.generateIndexFile(n,p,t),{results:p,errors:d,summary:{total:g.length,successful:p.length,failed:d.length}}}catch(g){throw new Error(`Batch conversion failed: ${g instanceof Error?g.message:String(g)}`)}}getComponentNames(t){return t.results.map(r=>r.componentName)}generateSummaryReport(t){let{summary:r,errors:n}=t,o=this.getComponentNames(t),s=`
47
+ === SVG Conversion Summary ===
48
+ `;return s+=`Total files processed: ${r.total}
49
+ `,s+=`Successful conversions: ${r.successful}
50
+ `,s+=`Failed conversions: ${r.failed}
51
+ `,o.length>0&&(s+=`
52
+ Generated components:
53
+ `,o.forEach(i=>{s+=` - ${i}
54
+ `;})),n.length>0&&(s+=`
55
+ Errors:
56
+ `,n.forEach(i=>{s+=` - ${i.file}: ${i.error}
57
+ `;})),s}async getSvgFiles(t,r,n){let o=[],s=await readdir(t);for(let i of s){let a=join(t,i),m=await stat(a);if(m.isDirectory()&&r){let p=await this.getSvgFiles(a,r,n);o.push(...p);}else m.isFile()&&n.includes(extname(i).toLowerCase())&&o.push(a);}return o}async generateIndexFile(t,r,n){let{indexFormat:o="ts",exportType:s="named",typescript:i=true}=n,a=z(r,{format:o,exportType:s,typescript:i}),m=`index.${o}`,p=join(t,m);await w(p,a);}async getComponentNameFromFile(t,r){let n=basename(t,extname(t)),{prefix:o="",suffix:s=""}=r,{pascalCase:i}=await Promise.resolve().then(()=>(D(),L)),a=i(n);return o&&(a=`${i(o)}${a}`),s&&(a=`${a}${i(s)}`),a}async getOutputPath(t,r,n,o){let s=t.replace(r,"").replace(/^[/\\]/,""),i=s.includes("/")?s.substring(0,s.lastIndexOf("/")):s.includes("\\")?s.substring(0,s.lastIndexOf("\\")):"",a=i?join(n,i,o):join(n,o);return await R(dirname(a)),a}};export{j as BatchConverter,we as convertToReact,be as convertToVue,ie as createSvgoConfig,h as formatComponentName,z as generateIndexFile,I as optimizeSvg,v as pascalCase,T as readSvgDirectory,Z as readSvgFile,pe as sanitizeComponentName,ae as svgToComponentName,w as writeComponentFile,W as writeSvgFile};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svgfusion",
3
- "version": "1.5.0",
3
+ "version": "1.6.0",
4
4
  "description": "A powerful CLI tool and library that converts SVG files into production-ready React and Vue 3 components with TypeScript support and automatic optimization.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",