svgfusion 1.0.6 → 1.1.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/cli.js +137 -21
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +3 -1
package/dist/cli.js
CHANGED
|
@@ -125,6 +125,51 @@ var init_files = __esm({
|
|
|
125
125
|
init_cjs_shims();
|
|
126
126
|
var import_commander = require("commander");
|
|
127
127
|
init_files();
|
|
128
|
+
var import_promises2 = require("fs/promises");
|
|
129
|
+
var import_path2 = require("path");
|
|
130
|
+
|
|
131
|
+
// src/utils/name.ts
|
|
132
|
+
init_cjs_shims();
|
|
133
|
+
function svgToComponentName(filename) {
|
|
134
|
+
let baseName = filename.replace(/\.svg$/i, "");
|
|
135
|
+
baseName = processComplexFilename(baseName);
|
|
136
|
+
return pascalCase(baseName);
|
|
137
|
+
}
|
|
138
|
+
function processComplexFilename(filename) {
|
|
139
|
+
let processed = filename;
|
|
140
|
+
const simpleMatch = processed.match(/^([^,]+),\s*Type=([^,]+)/i);
|
|
141
|
+
if (simpleMatch) {
|
|
142
|
+
processed = `${simpleMatch[1]} ${simpleMatch[2]}`;
|
|
143
|
+
return processed;
|
|
144
|
+
}
|
|
145
|
+
const sizeMatch = processed.match(/Size=(\w+)/i);
|
|
146
|
+
const colorMatch = processed.match(/Color=(\w+)/i);
|
|
147
|
+
const typeMatch = processed.match(/Type=(\w+)/i);
|
|
148
|
+
if (sizeMatch || colorMatch || typeMatch) {
|
|
149
|
+
const parts = [];
|
|
150
|
+
if (typeMatch) parts.push(typeMatch[1]);
|
|
151
|
+
if (colorMatch) parts.push(colorMatch[1]);
|
|
152
|
+
if (sizeMatch) parts.push(sizeMatch[1]);
|
|
153
|
+
if (parts.length > 0) {
|
|
154
|
+
processed = parts.join(" ");
|
|
155
|
+
return processed;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
processed = processed.replace(/\b\w+=\w+\b/g, "").replace(/,\s*/g, " ").replace(/[=]/g, " ").replace(/\s+/g, " ").trim();
|
|
159
|
+
if (!processed || processed.length < 2) {
|
|
160
|
+
processed = filename;
|
|
161
|
+
}
|
|
162
|
+
return processed;
|
|
163
|
+
}
|
|
164
|
+
function pascalCase(str) {
|
|
165
|
+
return str.replace(/[^a-zA-Z0-9]/g, " ").split(/\s+/).filter((word) => word.length > 0).map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join("");
|
|
166
|
+
}
|
|
167
|
+
function formatComponentName(name, prefix, suffix) {
|
|
168
|
+
const prefixPart = prefix ? pascalCase(prefix) : "";
|
|
169
|
+
const suffixPart = suffix ? pascalCase(suffix) : "";
|
|
170
|
+
const baseName = pascalCase(name);
|
|
171
|
+
return `${prefixPart}${baseName}${suffixPart}`;
|
|
172
|
+
}
|
|
128
173
|
|
|
129
174
|
// src/core/react-converter.ts
|
|
130
175
|
init_cjs_shims();
|
|
@@ -170,18 +215,6 @@ function optimizeSvg(svgContent, config = defaultConfig) {
|
|
|
170
215
|
}
|
|
171
216
|
}
|
|
172
217
|
|
|
173
|
-
// src/utils/name.ts
|
|
174
|
-
init_cjs_shims();
|
|
175
|
-
function pascalCase(str) {
|
|
176
|
-
return str.replace(/[^a-zA-Z0-9\s-_]/g, " ").split(/[\s-_]+/).filter((word) => word.length > 0).map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join("");
|
|
177
|
-
}
|
|
178
|
-
function formatComponentName(name, prefix, suffix) {
|
|
179
|
-
const prefixPart = prefix ? pascalCase(prefix) : "";
|
|
180
|
-
const suffixPart = suffix ? pascalCase(suffix) : "";
|
|
181
|
-
const baseName = pascalCase(name);
|
|
182
|
-
return `${prefixPart}${baseName}${suffixPart}`;
|
|
183
|
-
}
|
|
184
|
-
|
|
185
218
|
// src/core/converter.ts
|
|
186
219
|
var BaseConverter = class {
|
|
187
220
|
/**
|
|
@@ -508,7 +541,7 @@ async function convertToVue(svgContent, options = {}) {
|
|
|
508
541
|
|
|
509
542
|
// src/cli.ts
|
|
510
543
|
var import_url = require("url");
|
|
511
|
-
var
|
|
544
|
+
var import_path3 = require("path");
|
|
512
545
|
var import_fs2 = require("fs");
|
|
513
546
|
var import_figlet = __toESM(require("figlet"));
|
|
514
547
|
var colors = {
|
|
@@ -517,23 +550,80 @@ var colors = {
|
|
|
517
550
|
green: "\x1B[32m",
|
|
518
551
|
red: "\x1B[31m",
|
|
519
552
|
gray: "\x1B[90m",
|
|
553
|
+
dim: "\x1B[2m",
|
|
554
|
+
// Bold gradient colors with dramatic artistic accents
|
|
555
|
+
darkBlue: "\x1B[38;2;0;100;255m",
|
|
556
|
+
// Electric blue (bold)
|
|
557
|
+
mediumBlue: "\x1B[38;2;50;150;255m",
|
|
558
|
+
// Bright blue
|
|
559
|
+
lightBlue: "\x1B[38;2;100;200;255m",
|
|
560
|
+
// Vivid sky blue
|
|
561
|
+
blueCyan: "\x1B[38;2;0;150;255m",
|
|
562
|
+
// Electric blue-cyan
|
|
563
|
+
mediumCyan: "\x1B[38;2;0;255;255m",
|
|
564
|
+
// Pure cyan (bold)
|
|
565
|
+
darkCyan: "\x1B[38;2;0;200;200m",
|
|
566
|
+
// Electric turquoise
|
|
567
|
+
softTeal: "\x1B[38;2;0;255;150m",
|
|
568
|
+
// Electric teal
|
|
569
|
+
tealGreen: "\x1B[38;2;0;200;100m",
|
|
570
|
+
// Vivid teal green
|
|
571
|
+
softGreen: "\x1B[38;2;50;255;100m",
|
|
572
|
+
// Electric green
|
|
573
|
+
mediumGreen: "\x1B[38;2;0;255;50m",
|
|
574
|
+
// Pure green (bold)
|
|
520
575
|
reset: "\x1B[0m"
|
|
521
576
|
};
|
|
522
577
|
var __filename2 = (0, import_url.fileURLToPath)(importMetaUrl);
|
|
523
|
-
var __dirname = (0,
|
|
578
|
+
var __dirname = (0, import_path3.dirname)(__filename2);
|
|
524
579
|
var packageJson = JSON.parse(
|
|
525
|
-
(0, import_fs2.readFileSync)((0,
|
|
580
|
+
(0, import_fs2.readFileSync)((0, import_path3.join)(__dirname, "..", "package.json"), "utf-8")
|
|
526
581
|
);
|
|
527
582
|
function createBanner() {
|
|
528
583
|
const title = import_figlet.default.textSync("SVGfusion", {
|
|
529
|
-
font: "
|
|
584
|
+
font: "ANSI Shadow",
|
|
530
585
|
horizontalLayout: "default",
|
|
531
586
|
verticalLayout: "default",
|
|
532
587
|
width: 80,
|
|
533
588
|
whitespaceBreak: true
|
|
534
589
|
});
|
|
590
|
+
const lines = title.split("\n");
|
|
591
|
+
const totalLines = lines.length;
|
|
592
|
+
const gradientTitle = lines.map((line, lineIndex) => {
|
|
593
|
+
const chars = line.split("");
|
|
594
|
+
const processedLine = chars.map((char, charIndex) => {
|
|
595
|
+
const y = (totalLines - 1 - lineIndex) / (totalLines - 1);
|
|
596
|
+
const x = charIndex / (line.length - 1 || 1);
|
|
597
|
+
const diagonalProgress = (x + y) / 2;
|
|
598
|
+
if (char.trim() === "") {
|
|
599
|
+
return char;
|
|
600
|
+
}
|
|
601
|
+
if (diagonalProgress <= 0.1) {
|
|
602
|
+
return `${colors.darkBlue}${char}${colors.reset}`;
|
|
603
|
+
} else if (diagonalProgress <= 0.2) {
|
|
604
|
+
return `${colors.lightBlue}${char}${colors.reset}`;
|
|
605
|
+
} else if (diagonalProgress <= 0.32) {
|
|
606
|
+
return `${colors.mediumBlue}${char}${colors.reset}`;
|
|
607
|
+
} else if (diagonalProgress <= 0.42) {
|
|
608
|
+
return `${colors.blueCyan}${char}${colors.reset}`;
|
|
609
|
+
} else if (diagonalProgress <= 0.52) {
|
|
610
|
+
return `${colors.mediumCyan}${char}${colors.reset}`;
|
|
611
|
+
} else if (diagonalProgress <= 0.62) {
|
|
612
|
+
return `${colors.darkCyan}${char}${colors.reset}`;
|
|
613
|
+
} else if (diagonalProgress <= 0.72) {
|
|
614
|
+
return `${colors.softTeal}${char}${colors.reset}`;
|
|
615
|
+
} else if (diagonalProgress <= 0.82) {
|
|
616
|
+
return `${colors.tealGreen}${char}${colors.reset}`;
|
|
617
|
+
} else if (diagonalProgress <= 0.92) {
|
|
618
|
+
return `${colors.softGreen}${char}${colors.reset}`;
|
|
619
|
+
} else {
|
|
620
|
+
return `${colors.mediumGreen}${char}${colors.reset}`;
|
|
621
|
+
}
|
|
622
|
+
}).join("");
|
|
623
|
+
return processedLine;
|
|
624
|
+
}).join("\n");
|
|
535
625
|
return `
|
|
536
|
-
${
|
|
626
|
+
${gradientTitle}
|
|
537
627
|
|
|
538
628
|
${colors.gray}Transform SVG files into production-ready components${colors.reset}
|
|
539
629
|
${colors.blue}React${colors.reset} ${colors.gray}\u2022${colors.reset} ${colors.green}Vue 3${colors.reset} ${colors.gray}\u2022${colors.reset} ${colors.blue}TypeScript${colors.reset}
|
|
@@ -542,7 +632,10 @@ ${colors.gray}\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
|
542
632
|
`;
|
|
543
633
|
}
|
|
544
634
|
var program = new import_commander.Command();
|
|
545
|
-
|
|
635
|
+
var isNpxCall = process.argv[1]?.includes("npx") || process.argv[1]?.includes("_npx");
|
|
636
|
+
if (process.argv.length === 2 || isNpxCall && process.argv.length === 3) {
|
|
637
|
+
console.log(createBanner());
|
|
638
|
+
}
|
|
546
639
|
program.name("svgfusion").description(
|
|
547
640
|
"Transform SVG files into production-ready React and Vue 3 components"
|
|
548
641
|
).version(packageJson.version);
|
|
@@ -559,7 +652,19 @@ program.command("convert").description("Convert SVG files to React or Vue compon
|
|
|
559
652
|
if (framework !== "react" && framework !== "vue") {
|
|
560
653
|
throw new Error('Framework must be either "react" or "vue"');
|
|
561
654
|
}
|
|
562
|
-
const
|
|
655
|
+
const inputStat = await (0, import_promises2.stat)(input);
|
|
656
|
+
let svgFiles;
|
|
657
|
+
if (inputStat.isFile()) {
|
|
658
|
+
if ((0, import_path2.extname)(input).toLowerCase() === ".svg") {
|
|
659
|
+
svgFiles = [input];
|
|
660
|
+
} else {
|
|
661
|
+
throw new Error("Input file must be an SVG file");
|
|
662
|
+
}
|
|
663
|
+
} else if (inputStat.isDirectory()) {
|
|
664
|
+
svgFiles = await readSvgDirectory(input);
|
|
665
|
+
} else {
|
|
666
|
+
throw new Error("Input must be a file or directory");
|
|
667
|
+
}
|
|
563
668
|
if (svgFiles.length === 0) {
|
|
564
669
|
throw new Error("No SVG files found in the input path");
|
|
565
670
|
}
|
|
@@ -569,13 +674,24 @@ program.command("convert").description("Convert SVG files to React or Vue compon
|
|
|
569
674
|
for (const filePath of svgFiles) {
|
|
570
675
|
const svgContent = await readSvgFile(filePath);
|
|
571
676
|
const optimizedSvg = optimize2 ? optimizeSvg(svgContent) : svgContent;
|
|
572
|
-
const
|
|
573
|
-
const
|
|
677
|
+
const filename = (0, import_path2.basename)(filePath);
|
|
678
|
+
const componentName = svgToComponentName(filename);
|
|
679
|
+
const result = framework === "react" ? await convertToReact(optimizedSvg, {
|
|
680
|
+
typescript,
|
|
681
|
+
name: componentName
|
|
682
|
+
}) : await convertToVue(optimizedSvg, {
|
|
683
|
+
typescript,
|
|
684
|
+
name: componentName
|
|
685
|
+
});
|
|
686
|
+
const outputPath = (0, import_path3.join)(output, result.filename);
|
|
574
687
|
await writeComponentFile(outputPath, result.code);
|
|
575
688
|
}
|
|
576
689
|
console.log(
|
|
577
690
|
`${colors.green}\u2705 Successfully converted ${svgFiles.length} SVG file(s) to ${framework} components${colors.reset}`
|
|
578
691
|
);
|
|
692
|
+
console.log(
|
|
693
|
+
`${colors.dim}\u{1F4C1} Output location: ${colors.reset}${colors.cyan}${output}${colors.reset}`
|
|
694
|
+
);
|
|
579
695
|
} catch (error) {
|
|
580
696
|
console.error(
|
|
581
697
|
`${colors.red}\u274C Error: ${error instanceof Error ? error.message : "Unknown error"}${colors.reset}`
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
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 I=Object.getOwnPropertyDescriptor;var L=Object.getOwnPropertyNames;var k=Object.prototype.hasOwnProperty;var R=(e,r)=>()=>(e&&(r=e(e=0)),r);var
|
|
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 I=Object.getOwnPropertyDescriptor;var L=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});},M=(e,r,t,o)=>{if(r&&typeof r=="object"||typeof r=="function")for(let n of L(r))!k.call(e,n)&&n!==t&&d(e,n,{get:()=>r[n],enumerable:!(o=I(r,n))||o.enumerable});return e};var _=e=>M(d({},"__esModule",{value:true}),e);var a=R(()=>{});var T={};q(T,{ensureDirectoryExists:()=>h,getComponentFilename:()=>ie,getFileExtension:()=>se,readSvgDirectory:()=>x,readSvgFile:()=>O,writeComponentFile:()=>D,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 h(path.dirname(e)),await promises.writeFile(e,r,"utf-8");}catch(t){throw new Error(`Failed to write SVG file: ${e}. ${t}`)}}async function D(e,r){try{await h(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),i=await promises.stat(s);if(i.isDirectory()&&r){let p=await x(s,r);o.push(...p);}else i.isFile()&&path.extname(n).toLowerCase()===".svg"&&o.push(s);}return o}catch(t){throw new Error(`Failed to read directory: ${e}. ${t}`)}}async function h(e){fs.existsSync(e)||await promises.mkdir(e,{recursive:true});}function se(e,r=true){return e==="react"?r?".tsx":".jsx":".vue"}function ie(e,r,t){return `${r}${t}`}var w=R(()=>{a();});a();a();a();a();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}}a();function K(e){let r=e.replace(/\.svg$/i,"");return r=Q(r),u(r)}function Q(e){let r=e,t=r.match(/^([^,]+),\s*Type=([^,]+)/i);if(t)return r=`${t[1]} ${t[2]}`,r;let o=r.match(/Size=(\w+)/i),n=r.match(/Color=(\w+)/i),s=r.match(/Type=(\w+)/i);if(o||n||s){let i=[];if(s&&i.push(s[1]),n&&i.push(n[1]),o&&i.push(o[1]),i.length>0)return r=i.join(" "),r}return r=r.replace(/\b\w+=\w+\b/g,"").replace(/,\s*/g," ").replace(/[=]/g," ").replace(/\s+/g," ").trim(),(!r||r.length<2)&&(r=e),r}function W(e){return u(e.replace(/[^a-zA-Z0-9]/g," "))}function u(e){return e.replace(/[^a-zA-Z0-9]/g," ").split(/\s+/).filter(r=>r.length>0).map(r=>r.charAt(0).toUpperCase()+r.slice(1).toLowerCase()).join("")}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}=(w(),_(T)),i=n(t,o);return s("icon.svg",r,i)}catch{return `${r}${{react:o?".tsx":".jsx",vue:".vue"}[t]}`}}};a();function U(e){let{typescript:r=true,memo:t=true,ref:o=true,titleProp:n=true,descProp:s=true,icon:i=true,dimensions:p=false,replaceAttrValues:c={"#000":"currentColor","#000000":"currentColor"},svgProps:l={},expandProps:v=false,nativeProps:E=true,ariaLabelledBy:j=false,ariaHidden:B=false,role:G="img"}=e,b={typescript:r,memo:t,ref:o,titleProp:n,descProp:s,icon:i,dimensions:p,expandProps:v,svgProps:{className:"{className}",...o&&{ref:"{ref}"},...E&&{width:"{width}",height:"{height}",style:"{style}"},...j&&n&&s&&{"aria-labelledby":"{titleId} {descId}"},...B&&{"aria-hidden":"true"},role:G,...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}}},...i&&!p?[{name:"removeAttrs",params:{attrs:["width","height"]}}]:[],...i?["cleanupNumericValues"]:[]]},b}function A(e,r,t){let o=e;return y(o)&&(o=$(o,r)),o}function y(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 S=class extends g{async convert(r,t={}){try{let o=this.generateComponentName(t),n=await this.processSvg(r,t);y(n)&&(n=$(n,o));let s=U(t),i=await core.transform(n,s,{componentName:o}),p=A(i,o,t),c=this.generateFilename(o,"react",t.typescript??!0);return {code:p,filename:c,componentName:o}}catch(o){throw new Error(`Failed to convert SVG to React: ${o}`)}}};async function ce(e,r={}){return new S().convert(e,r)}a();a();function z(e,r){let{name:t,prefix:o,suffix:n,props:s=true,replaceAttrValues:i={"#000":"currentColor","#000000":"currentColor"}}=r,c=f(t||"Icon",o,n),l=le(e);return l=pe(l,i),me(l)&&(l=ue(l,c)),l=ge(l,s),{code:fe(l,c,r),componentName:c}}function le(e){return e.replace(/<\?xml[^>]*\?>\s*/,"").replace(/<!--[\s\S]*?-->/g,"").replace(/xmlns="[^"]*"/g,"").trim()}function pe(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 me(e){return ["linearGradient","radialGradient","pattern","mask","filter","clipPath","marker","symbol","use"].some(t=>e.includes(`<${t}`)||e.includes(`</${t}`))}function ue(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 ge(e,r){return r?e.replace("<svg",'<svg :class="className" :style="style" v-bind="$attrs"'):e}function fe(e,r,t){let{typescript:o,compositionApi:n,props:s}=t,c=`<script${o?' lang="ts"':""}${n?" setup":""}>`;n?s&&(c+=`
|
|
2
2
|
interface Props {
|
|
3
3
|
className?: string;
|
|
4
4
|
style?: Record<string, any>;
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
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
|
|
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 L=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});},M=(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=L(r,n))||o.enumerable});return e};var Z=e=>M(d({},"__esModule",{value:true}),e);var a=N(()=>{});var A={};q(A,{ensureDirectoryExists:()=>w,getComponentFilename:()=>ae,getFileExtension:()=>ie,readSvgDirectory:()=>h,readSvgFile:()=>O,writeComponentFile:()=>T,writeSvgFile:()=>D});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 D(e,r){try{await w(dirname(e)),await writeFile(e,r,"utf-8");}catch(t){throw new Error(`Failed to write SVG file: ${e}. ${t}`)}}async function T(e,r){try{await w(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),i=await stat(s);if(i.isDirectory()&&r){let p=await h(s,r);o.push(...p);}else i.isFile()&&extname(n).toLowerCase()===".svg"&&o.push(s);}return o}catch(t){throw new Error(`Failed to read directory: ${e}. ${t}`)}}async function w(e){existsSync(e)||await 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 y=N(()=>{a();});a();a();a();a();var J={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=J){try{return optimize(e,r).data}catch(t){throw new Error(`Failed to optimize SVG: ${t}`)}}function K(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}}a();function Q(e){let r=e.replace(/\.svg$/i,"");return r=W(r),g(r)}function W(e){let r=e,t=r.match(/^([^,]+),\s*Type=([^,]+)/i);if(t)return r=`${t[1]} ${t[2]}`,r;let o=r.match(/Size=(\w+)/i),n=r.match(/Color=(\w+)/i),s=r.match(/Type=(\w+)/i);if(o||n||s){let i=[];if(s&&i.push(s[1]),n&&i.push(n[1]),o&&i.push(o[1]),i.length>0)return r=i.join(" "),r}return r=r.replace(/\b\w+=\w+\b/g,"").replace(/,\s*/g," ").replace(/[=]/g," ").replace(/\s+/g," ").trim(),(!r||r.length<2)&&(r=e),r}function X(e){return g(e.replace(/[^a-zA-Z0-9]/g," "))}function g(e){return e.replace(/[^a-zA-Z0-9]/g," ").split(/\s+/).filter(r=>r.length>0).map(r=>r.charAt(0).toUpperCase()+r.slice(1).toLowerCase()).join("")}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}=(y(),Z(A)),i=n(t,o);return s("icon.svg",r,i)}catch{return `${r}${{react:o?".tsx":".jsx",vue:".vue"}[t]}`}}};a();function z(e){let{typescript:r=true,memo:t=true,ref:o=true,titleProp:n=true,descProp:s=true,icon:i=true,dimensions:p=false,replaceAttrValues:c={"#000":"currentColor","#000000":"currentColor"},svgProps:l={},expandProps:C=false,nativeProps:B=true,ariaLabelledBy:U=false,ariaHidden:G=false,role:k="img"}=e,V={typescript:r,memo:t,ref:o,titleProp:n,descProp:s,icon:i,dimensions:p,expandProps:C,svgProps:{className:"{className}",...o&&{ref:"{ref}"},...B&&{width:"{width}",height:"{height}",style:"{style}"},...U&&n&&s&&{"aria-labelledby":"{titleId} {descId}"},...G&&{"aria-hidden":"true"},role:k,...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}}},...i&&!p?[{name:"removeAttrs",params:{attrs:["width","height"]}}]:[],...i?["cleanupNumericValues"]:[]]},V}function E(e,r,t){let o=e;return $(o)&&(o=F(o,r)),o}function $(e){return ["linearGradient","radialGradient","pattern","mask","filter","clipPath","marker","symbol","use"].some(t=>e.includes(`<${t}`)||e.includes(`</${t}`))}function F(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 S=class extends f{async convert(r,t={}){try{let o=this.generateComponentName(t),n=await this.processSvg(r,t);$(n)&&(n=F(n,o));let s=z(t),i=await transform(n,s,{componentName:o}),p=E(i,o,t),c=this.generateFilename(o,"react",t.typescript??!0);return {code:p,filename:c,componentName:o}}catch(o){throw new Error(`Failed to convert SVG to React: ${o}`)}}};async function le(e,r={}){return new S().convert(e,r)}a();a();function j(e,r){let{name:t,prefix:o,suffix:n,props:s=true,replaceAttrValues:i={"#000":"currentColor","#000000":"currentColor"}}=r,c=v(t||"Icon",o,n),l=pe(e);return l=me(l,i),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+=`
|
|
2
2
|
interface Props {
|
|
3
3
|
className?: string;
|
|
4
4
|
style?: Record<string, any>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svgfusion",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.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",
|
|
@@ -63,6 +63,7 @@
|
|
|
63
63
|
"scripts": {
|
|
64
64
|
"build": "tsup && chmod +x dist/cli.js",
|
|
65
65
|
"dev": "tsup --watch",
|
|
66
|
+
"watch": "nodemon --watch src --ext ts --exec 'pnpm run build'",
|
|
66
67
|
"test": "jest",
|
|
67
68
|
"test:coverage": "jest --coverage --json --testLocationInResults --outputFile=./coverage/coverage-summary.json",
|
|
68
69
|
"test:watch": "jest --watch",
|
|
@@ -107,6 +108,7 @@
|
|
|
107
108
|
"husky": "^8.0.3",
|
|
108
109
|
"jest": "^30.0.4",
|
|
109
110
|
"lint-staged": "^15.2.2",
|
|
111
|
+
"nodemon": "^3.1.10",
|
|
110
112
|
"prettier": "^2.8.8",
|
|
111
113
|
"semantic-release": "^24.2.6",
|
|
112
114
|
"ts-jest": "^29.4.0",
|