vectify 2.0.1 → 2.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +67 -0
- package/README.zh-CN.md +67 -0
- package/dist/{chunk-F3AM6WVC.mjs → chunk-XHYCGABW.mjs} +124 -22
- package/dist/cli.js +134 -31
- package/dist/cli.mjs +1 -1
- package/dist/index.d.mts +37 -1
- package/dist/index.d.ts +37 -1
- package/dist/index.js +130 -27
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -20,6 +20,7 @@ English | [简体中文](./README.zh-CN.md)
|
|
|
20
20
|
- [Configuration](#configuration)
|
|
21
21
|
- [Basic Options](#basic-options)
|
|
22
22
|
- [Generation Options](#generation-options)
|
|
23
|
+
- [Auto Formatting](#auto-formatting)
|
|
23
24
|
- [Watch Mode](#watch-mode)
|
|
24
25
|
- [SVGO Configuration](#svgo-configuration)
|
|
25
26
|
- [Lifecycle Hooks](#lifecycle-hooks)
|
|
@@ -185,6 +186,7 @@ All available options for `defineConfig()` are documented in the tables below.
|
|
|
185
186
|
| `prefix` | `string` | `''` | ❌ | Prefix added to all component names. Useful for namespacing. | `prefix: 'Icon'` → `IconArrowRight` |
|
|
186
187
|
| `suffix` | `string` | `''` | ❌ | Suffix added to all component names. | `suffix: 'Icon'` → `ArrowRightIcon` |
|
|
187
188
|
| `transform` | `(name: string) => string` | - | ❌ | Custom function to transform SVG filename to component name. Overrides default PascalCase conversion and prefix/suffix. | `transform: (n) => 'X' + n` |
|
|
189
|
+
| `format` | `boolean` \| `'prettier'` \| `'eslint'` \| `'biome'` \| `FormatConfig` | `false` | ❌ | Auto-format generated files after generation. See [Auto Formatting](#auto-formatting) for details. | `format: true` |
|
|
188
190
|
|
|
189
191
|
#### `generateOptions` Object
|
|
190
192
|
|
|
@@ -195,6 +197,71 @@ All available options for `defineConfig()` are documented in the tables below.
|
|
|
195
197
|
| `preview` | `boolean` | `false` | Generate interactive `preview.html` for browsing all icons locally. Useful for design review. | `preview: true` |
|
|
196
198
|
| `cleanOutput` | `boolean` | `false` | Remove orphaned component files that no longer have corresponding SVG files. Helps keep output directory clean. | `cleanOutput: true` |
|
|
197
199
|
|
|
200
|
+
#### Auto Formatting
|
|
201
|
+
|
|
202
|
+
Vectify can automatically format generated files using your project's formatter. This ensures generated code matches your project's code style.
|
|
203
|
+
|
|
204
|
+
**Quick Start:**
|
|
205
|
+
|
|
206
|
+
```typescript
|
|
207
|
+
export default defineConfig({
|
|
208
|
+
framework: 'react',
|
|
209
|
+
input: './icons',
|
|
210
|
+
output: './src/icons',
|
|
211
|
+
format: true, // Auto-detect and use project formatter
|
|
212
|
+
})
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
**Format Options:**
|
|
216
|
+
|
|
217
|
+
| Value | Description |
|
|
218
|
+
|-------|-------------|
|
|
219
|
+
| `false` | Disable formatting (default) |
|
|
220
|
+
| `true` | Auto-detect formatter (biome > prettier > eslint) |
|
|
221
|
+
| `'prettier'` | Use Prettier |
|
|
222
|
+
| `'eslint'` | Use ESLint --fix |
|
|
223
|
+
| `'biome'` | Use Biome |
|
|
224
|
+
| `{ tool, args }` | Full configuration object |
|
|
225
|
+
|
|
226
|
+
**Auto-Detection Priority:**
|
|
227
|
+
|
|
228
|
+
When `format: true`, Vectify looks for config files in this order:
|
|
229
|
+
1. `biome.json` / `biome.jsonc` → Uses Biome
|
|
230
|
+
2. `.prettierrc*` / `prettier.config.*` → Uses Prettier
|
|
231
|
+
3. `eslint.config.*` / `.eslintrc*` → Uses ESLint
|
|
232
|
+
|
|
233
|
+
**Full Configuration:**
|
|
234
|
+
|
|
235
|
+
```typescript
|
|
236
|
+
export default defineConfig({
|
|
237
|
+
format: {
|
|
238
|
+
tool: 'prettier', // 'auto' | 'prettier' | 'eslint' | 'biome'
|
|
239
|
+
args: '--single-quote', // Additional CLI arguments
|
|
240
|
+
},
|
|
241
|
+
})
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
**Examples:**
|
|
245
|
+
|
|
246
|
+
```typescript
|
|
247
|
+
// Auto-detect formatter
|
|
248
|
+
format: true
|
|
249
|
+
|
|
250
|
+
// Use specific formatter
|
|
251
|
+
format: 'prettier'
|
|
252
|
+
format: 'eslint'
|
|
253
|
+
format: 'biome'
|
|
254
|
+
|
|
255
|
+
// With custom arguments
|
|
256
|
+
format: {
|
|
257
|
+
tool: 'prettier',
|
|
258
|
+
args: '--tab-width 4',
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// Disable formatting
|
|
262
|
+
format: false
|
|
263
|
+
```
|
|
264
|
+
|
|
198
265
|
#### `watch` Object
|
|
199
266
|
|
|
200
267
|
| Parameter | Type | Default | Description | Example |
|
package/README.zh-CN.md
CHANGED
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
- [配置选项](#配置选项)
|
|
21
21
|
- [基础配置](#基础配置)
|
|
22
22
|
- [生成选项](#生成选项)
|
|
23
|
+
- [自动格式化](#自动格式化)
|
|
23
24
|
- [监听模式](#监听模式)
|
|
24
25
|
- [SVGO 配置](#svgo-配置)
|
|
25
26
|
- [生命周期钩子](#生命周期钩子)
|
|
@@ -185,6 +186,7 @@ npx vectify watch [选项]
|
|
|
185
186
|
| `prefix` | `string` | `''` | ❌ | 添加到所有组件名称前的前缀。用于命名空间 | `prefix: 'Icon'` → `IconArrowRight` |
|
|
186
187
|
| `suffix` | `string` | `''` | ❌ | 添加到所有组件名称后的后缀 | `suffix: 'Icon'` → `ArrowRightIcon` |
|
|
187
188
|
| `transform` | `(name: string) => string` | - | ❌ | 自定义函数,将 SVG 文件名转换为组件名。覆盖默认的 PascalCase 转换和 prefix/suffix | `transform: (n) => 'X' + n` |
|
|
189
|
+
| `format` | `boolean` \| `'prettier'` \| `'eslint'` \| `'biome'` \| `FormatConfig` | `false` | ❌ | 生成后自动格式化文件。详见 [自动格式化](#自动格式化) | `format: true` |
|
|
188
190
|
|
|
189
191
|
#### `generateOptions` 对象
|
|
190
192
|
|
|
@@ -195,6 +197,71 @@ npx vectify watch [选项]
|
|
|
195
197
|
| `preview` | `boolean` | `false` | 生成交互式 `preview.html` 用于本地浏览所有图标。适合设计审查 | `preview: true` |
|
|
196
198
|
| `cleanOutput` | `boolean` | `false` | 移除不再有对应 SVG 文件的孤立组件。帮助保持输出目录整洁 | `cleanOutput: true` |
|
|
197
199
|
|
|
200
|
+
#### 自动格式化
|
|
201
|
+
|
|
202
|
+
Vectify 可以使用项目中的格式化工具自动格式化生成的文件。确保生成的代码符合项目的代码风格。
|
|
203
|
+
|
|
204
|
+
**快速开始:**
|
|
205
|
+
|
|
206
|
+
```typescript
|
|
207
|
+
export default defineConfig({
|
|
208
|
+
framework: 'react',
|
|
209
|
+
input: './icons',
|
|
210
|
+
output: './src/icons',
|
|
211
|
+
format: true, // 自动检测并使用项目格式化工具
|
|
212
|
+
})
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
**格式化选项:**
|
|
216
|
+
|
|
217
|
+
| 值 | 说明 |
|
|
218
|
+
|----|------|
|
|
219
|
+
| `false` | 禁用格式化(默认) |
|
|
220
|
+
| `true` | 自动检测格式化工具(biome > prettier > eslint) |
|
|
221
|
+
| `'prettier'` | 使用 Prettier |
|
|
222
|
+
| `'eslint'` | 使用 ESLint --fix |
|
|
223
|
+
| `'biome'` | 使用 Biome |
|
|
224
|
+
| `{ tool, args }` | 完整配置对象 |
|
|
225
|
+
|
|
226
|
+
**自动检测优先级:**
|
|
227
|
+
|
|
228
|
+
当 `format: true` 时,Vectify 按以下顺序查找配置文件:
|
|
229
|
+
1. `biome.json` / `biome.jsonc` → 使用 Biome
|
|
230
|
+
2. `.prettierrc*` / `prettier.config.*` → 使用 Prettier
|
|
231
|
+
3. `eslint.config.*` / `.eslintrc*` → 使用 ESLint
|
|
232
|
+
|
|
233
|
+
**完整配置:**
|
|
234
|
+
|
|
235
|
+
```typescript
|
|
236
|
+
export default defineConfig({
|
|
237
|
+
format: {
|
|
238
|
+
tool: 'prettier', // 'auto' | 'prettier' | 'eslint' | 'biome'
|
|
239
|
+
args: '--single-quote', // 额外的 CLI 参数
|
|
240
|
+
},
|
|
241
|
+
})
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
**示例:**
|
|
245
|
+
|
|
246
|
+
```typescript
|
|
247
|
+
// 自动检测格式化工具
|
|
248
|
+
format: true
|
|
249
|
+
|
|
250
|
+
// 使用指定的格式化工具
|
|
251
|
+
format: 'prettier'
|
|
252
|
+
format: 'eslint'
|
|
253
|
+
format: 'biome'
|
|
254
|
+
|
|
255
|
+
// 带自定义参数
|
|
256
|
+
format: {
|
|
257
|
+
tool: 'prettier',
|
|
258
|
+
args: '--tab-width 4',
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// 禁用格式化
|
|
262
|
+
format: false
|
|
263
|
+
```
|
|
264
|
+
|
|
198
265
|
#### `watch` 对象
|
|
199
266
|
|
|
200
267
|
| 参数 | 类型 | 默认值 | 说明 | 示例 |
|
|
@@ -639,7 +639,7 @@ async function findConfig() {
|
|
|
639
639
|
}
|
|
640
640
|
|
|
641
641
|
// src/generators/index.ts
|
|
642
|
-
import
|
|
642
|
+
import path4 from "path";
|
|
643
643
|
|
|
644
644
|
// src/parsers/optimizer.ts
|
|
645
645
|
import { optimize } from "svgo";
|
|
@@ -673,6 +673,100 @@ async function optimizeSvg(svgContent, config) {
|
|
|
673
673
|
}
|
|
674
674
|
}
|
|
675
675
|
|
|
676
|
+
// src/utils/formatter.ts
|
|
677
|
+
import { exec } from "child_process";
|
|
678
|
+
import path3 from "path";
|
|
679
|
+
import process3 from "process";
|
|
680
|
+
import { promisify } from "util";
|
|
681
|
+
var execAsync = promisify(exec);
|
|
682
|
+
var FORMATTER_PATTERNS = {
|
|
683
|
+
biome: ["biome.json", "biome.jsonc"],
|
|
684
|
+
prettier: [
|
|
685
|
+
".prettierrc",
|
|
686
|
+
".prettierrc.json",
|
|
687
|
+
".prettierrc.yml",
|
|
688
|
+
".prettierrc.yaml",
|
|
689
|
+
".prettierrc.js",
|
|
690
|
+
".prettierrc.cjs",
|
|
691
|
+
".prettierrc.mjs",
|
|
692
|
+
"prettier.config.js",
|
|
693
|
+
"prettier.config.cjs",
|
|
694
|
+
"prettier.config.mjs"
|
|
695
|
+
],
|
|
696
|
+
eslint: [
|
|
697
|
+
"eslint.config.js",
|
|
698
|
+
"eslint.config.mjs",
|
|
699
|
+
"eslint.config.cjs",
|
|
700
|
+
"eslint.config.ts",
|
|
701
|
+
".eslintrc",
|
|
702
|
+
".eslintrc.js",
|
|
703
|
+
".eslintrc.cjs",
|
|
704
|
+
".eslintrc.json",
|
|
705
|
+
".eslintrc.yml",
|
|
706
|
+
".eslintrc.yaml"
|
|
707
|
+
]
|
|
708
|
+
};
|
|
709
|
+
var FORMATTER_COMMANDS = {
|
|
710
|
+
biome: (outputDir, args) => `npx @biomejs/biome format --write ${args || ""} "${outputDir}"`.trim(),
|
|
711
|
+
prettier: (outputDir, args) => `npx prettier --write ${args || ""} "${outputDir}"`.trim(),
|
|
712
|
+
eslint: (outputDir, args) => `npx eslint --fix ${args || ""} "${outputDir}"`.trim()
|
|
713
|
+
};
|
|
714
|
+
function normalizeFormatOption(format) {
|
|
715
|
+
if (format === false) {
|
|
716
|
+
return null;
|
|
717
|
+
}
|
|
718
|
+
if (format === true) {
|
|
719
|
+
return { tool: "auto" };
|
|
720
|
+
}
|
|
721
|
+
if (typeof format === "string") {
|
|
722
|
+
return { tool: format };
|
|
723
|
+
}
|
|
724
|
+
return format;
|
|
725
|
+
}
|
|
726
|
+
async function detectFormatter() {
|
|
727
|
+
const cwd = process3.cwd();
|
|
728
|
+
const priority = ["biome", "prettier", "eslint"];
|
|
729
|
+
for (const tool of priority) {
|
|
730
|
+
const patterns = FORMATTER_PATTERNS[tool];
|
|
731
|
+
for (const pattern of patterns) {
|
|
732
|
+
const configPath = path3.join(cwd, pattern);
|
|
733
|
+
if (await fileExists(configPath)) {
|
|
734
|
+
return tool;
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
return null;
|
|
739
|
+
}
|
|
740
|
+
async function formatOutput(outputDir, format) {
|
|
741
|
+
const config = normalizeFormatOption(format);
|
|
742
|
+
if (!config) {
|
|
743
|
+
return { success: true };
|
|
744
|
+
}
|
|
745
|
+
let tool = null;
|
|
746
|
+
if (config.tool === "auto") {
|
|
747
|
+
tool = await detectFormatter();
|
|
748
|
+
if (!tool) {
|
|
749
|
+
return {
|
|
750
|
+
success: true,
|
|
751
|
+
error: "No formatter detected. Install prettier, eslint, or biome to enable auto-formatting."
|
|
752
|
+
};
|
|
753
|
+
}
|
|
754
|
+
} else {
|
|
755
|
+
tool = config.tool || "prettier";
|
|
756
|
+
}
|
|
757
|
+
const command = FORMATTER_COMMANDS[tool](outputDir, config.args);
|
|
758
|
+
try {
|
|
759
|
+
await execAsync(command, { cwd: process3.cwd() });
|
|
760
|
+
return { success: true, tool };
|
|
761
|
+
} catch (error) {
|
|
762
|
+
return {
|
|
763
|
+
success: false,
|
|
764
|
+
tool,
|
|
765
|
+
error: `Format failed with ${tool}: ${error.message}`
|
|
766
|
+
};
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
|
|
676
770
|
// src/generators/index.ts
|
|
677
771
|
async function generateIcons(config, dryRun = false) {
|
|
678
772
|
const stats = {
|
|
@@ -714,6 +808,14 @@ async function generateIcons(config, dryRun = false) {
|
|
|
714
808
|
if (config.generateOptions?.preview && !dryRun) {
|
|
715
809
|
await generatePreviewHtml(svgFiles, config);
|
|
716
810
|
}
|
|
811
|
+
if (config.format && !dryRun) {
|
|
812
|
+
const formatResult = await formatOutput(config.output, config.format);
|
|
813
|
+
if (formatResult.success && formatResult.tool) {
|
|
814
|
+
console.log(`Formatted with ${formatResult.tool}`);
|
|
815
|
+
} else if (formatResult.error) {
|
|
816
|
+
console.warn(formatResult.error);
|
|
817
|
+
}
|
|
818
|
+
}
|
|
717
819
|
if (config.hooks?.onComplete) {
|
|
718
820
|
await config.hooks.onComplete(stats);
|
|
719
821
|
}
|
|
@@ -724,7 +826,7 @@ async function generateIcons(config, dryRun = false) {
|
|
|
724
826
|
}
|
|
725
827
|
async function generateIconComponent(svgFile, config, dryRun = false) {
|
|
726
828
|
let svgContent = await readFile(svgFile);
|
|
727
|
-
const fileName =
|
|
829
|
+
const fileName = path4.basename(svgFile);
|
|
728
830
|
if (config.hooks?.beforeParse) {
|
|
729
831
|
svgContent = await config.hooks.beforeParse(svgContent, fileName);
|
|
730
832
|
}
|
|
@@ -748,7 +850,7 @@ async function generateIconComponent(svgFile, config, dryRun = false) {
|
|
|
748
850
|
code = await config.hooks.afterGenerate(code, componentName);
|
|
749
851
|
}
|
|
750
852
|
const fileExt = strategy.getComponentExtension(typescript);
|
|
751
|
-
const outputPath =
|
|
853
|
+
const outputPath = path4.join(config.output, `${componentName}.${fileExt}`);
|
|
752
854
|
if (dryRun) {
|
|
753
855
|
console.log(` ${componentName}.${fileExt}`);
|
|
754
856
|
} else {
|
|
@@ -759,7 +861,7 @@ async function generateBaseComponent(config, dryRun = false) {
|
|
|
759
861
|
const typescript = config.typescript ?? true;
|
|
760
862
|
const strategy = getFrameworkStrategy(config.framework);
|
|
761
863
|
const { code, fileName } = strategy.generateBaseComponent(typescript);
|
|
762
|
-
const outputPath =
|
|
864
|
+
const outputPath = path4.join(config.output, fileName);
|
|
763
865
|
if (dryRun) {
|
|
764
866
|
console.log(` ${fileName}`);
|
|
765
867
|
} else {
|
|
@@ -772,7 +874,7 @@ async function generateIndexFile(svgFiles, config, dryRun = false) {
|
|
|
772
874
|
const ext = strategy.getIndexExtension(typescript);
|
|
773
875
|
const usesDefaultExport = ["vue", "svelte", "react", "preact"].includes(config.framework);
|
|
774
876
|
const exports = svgFiles.map((svgFile) => {
|
|
775
|
-
const fileName =
|
|
877
|
+
const fileName = path4.basename(svgFile);
|
|
776
878
|
const componentName = getComponentName(
|
|
777
879
|
fileName,
|
|
778
880
|
config.prefix,
|
|
@@ -785,7 +887,7 @@ async function generateIndexFile(svgFiles, config, dryRun = false) {
|
|
|
785
887
|
return `export { ${componentName} } from './${componentName}'`;
|
|
786
888
|
}
|
|
787
889
|
}).join("\n");
|
|
788
|
-
const indexPath =
|
|
890
|
+
const indexPath = path4.join(config.output, `index.${ext}`);
|
|
789
891
|
if (dryRun) {
|
|
790
892
|
console.log(` index.${ext}`);
|
|
791
893
|
} else {
|
|
@@ -795,7 +897,7 @@ async function generateIndexFile(svgFiles, config, dryRun = false) {
|
|
|
795
897
|
}
|
|
796
898
|
async function generatePreviewHtml(svgFiles, config) {
|
|
797
899
|
const componentNames = svgFiles.map((svgFile) => {
|
|
798
|
-
const fileName =
|
|
900
|
+
const fileName = path4.basename(svgFile);
|
|
799
901
|
return getComponentName(
|
|
800
902
|
fileName,
|
|
801
903
|
config.prefix,
|
|
@@ -967,7 +1069,7 @@ async function generatePreviewHtml(svgFiles, config) {
|
|
|
967
1069
|
</script>
|
|
968
1070
|
</body>
|
|
969
1071
|
</html>`;
|
|
970
|
-
const previewPath =
|
|
1072
|
+
const previewPath = path4.join(config.output, "preview.html");
|
|
971
1073
|
await writeFile(previewPath, html);
|
|
972
1074
|
}
|
|
973
1075
|
async function cleanOutputDirectory(svgFiles, config) {
|
|
@@ -976,7 +1078,7 @@ async function cleanOutputDirectory(svgFiles, config) {
|
|
|
976
1078
|
const fileExt = strategy.getComponentExtension(config.typescript ?? true);
|
|
977
1079
|
const expectedComponents = new Set(
|
|
978
1080
|
svgFiles.map((svgFile) => {
|
|
979
|
-
const fileName =
|
|
1081
|
+
const fileName = path4.basename(svgFile, ".svg");
|
|
980
1082
|
const componentName = getComponentName(
|
|
981
1083
|
fileName,
|
|
982
1084
|
config.prefix,
|
|
@@ -1003,7 +1105,7 @@ async function cleanOutputDirectory(svgFiles, config) {
|
|
|
1003
1105
|
continue;
|
|
1004
1106
|
}
|
|
1005
1107
|
if (!expectedComponents.has(file)) {
|
|
1006
|
-
const filePath =
|
|
1108
|
+
const filePath = path4.join(config.output, file);
|
|
1007
1109
|
await unlink(filePath);
|
|
1008
1110
|
console.log(`Deleted orphaned component: ${file}`);
|
|
1009
1111
|
}
|
|
@@ -1072,15 +1174,15 @@ ${chalk.bold("Output:")} ${chalk.cyan(config.output)}`);
|
|
|
1072
1174
|
}
|
|
1073
1175
|
|
|
1074
1176
|
// src/commands/init.ts
|
|
1075
|
-
import
|
|
1076
|
-
import
|
|
1177
|
+
import path5 from "path";
|
|
1178
|
+
import process4 from "process";
|
|
1077
1179
|
import chalk2 from "chalk";
|
|
1078
1180
|
import inquirer from "inquirer";
|
|
1079
1181
|
import ora2 from "ora";
|
|
1080
1182
|
async function init(options = {}) {
|
|
1081
1183
|
try {
|
|
1082
1184
|
const projectRoot = await findProjectRoot();
|
|
1083
|
-
const currentDir =
|
|
1185
|
+
const currentDir = process4.cwd();
|
|
1084
1186
|
if (currentDir !== projectRoot) {
|
|
1085
1187
|
console.log(chalk2.yellow(`
|
|
1086
1188
|
Note: Project root detected at ${chalk2.cyan(projectRoot)}`));
|
|
@@ -1101,8 +1203,8 @@ Note: Project root detected at ${chalk2.cyan(projectRoot)}`));
|
|
|
1101
1203
|
}
|
|
1102
1204
|
}
|
|
1103
1205
|
]);
|
|
1104
|
-
const configPath =
|
|
1105
|
-
const configDir =
|
|
1206
|
+
const configPath = path5.resolve(projectRoot, pathAnswers.configPath);
|
|
1207
|
+
const configDir = path5.dirname(configPath);
|
|
1106
1208
|
if (!options.force && await fileExists(configPath)) {
|
|
1107
1209
|
const { overwrite } = await inquirer.prompt([
|
|
1108
1210
|
{
|
|
@@ -1166,14 +1268,14 @@ Note: Project root detected at ${chalk2.cyan(projectRoot)}`));
|
|
|
1166
1268
|
default: ""
|
|
1167
1269
|
}
|
|
1168
1270
|
]);
|
|
1169
|
-
const inputPath =
|
|
1170
|
-
const outputPath =
|
|
1271
|
+
const inputPath = path5.resolve(projectRoot, answers.input);
|
|
1272
|
+
const outputPath = path5.resolve(projectRoot, answers.output);
|
|
1171
1273
|
const spinner = ora2("Setting up directories...").start();
|
|
1172
1274
|
await ensureDir(inputPath);
|
|
1173
1275
|
spinner.text = `Created input directory: ${chalk2.cyan(answers.input)}`;
|
|
1174
1276
|
await ensureDir(outputPath);
|
|
1175
1277
|
spinner.succeed(`Created output directory: ${chalk2.cyan(answers.output)}`);
|
|
1176
|
-
const relativeConfigDir =
|
|
1278
|
+
const relativeConfigDir = path5.relative(configDir, projectRoot) || ".";
|
|
1177
1279
|
const configContent = generateConfigContent(answers, relativeConfigDir);
|
|
1178
1280
|
spinner.start("Creating config file...");
|
|
1179
1281
|
await writeFile(configPath, configContent);
|
|
@@ -1216,7 +1318,7 @@ export default defineConfig({
|
|
|
1216
1318
|
}
|
|
1217
1319
|
|
|
1218
1320
|
// src/commands/watch.ts
|
|
1219
|
-
import
|
|
1321
|
+
import path6 from "path";
|
|
1220
1322
|
import chalk3 from "chalk";
|
|
1221
1323
|
import chokidar from "chokidar";
|
|
1222
1324
|
import ora3 from "ora";
|
|
@@ -1238,7 +1340,7 @@ async function watch(options = {}) {
|
|
|
1238
1340
|
spinner.start("Generating icon components...");
|
|
1239
1341
|
const initialStats = await generateIcons(config);
|
|
1240
1342
|
spinner.succeed(`Generated ${chalk3.green(initialStats.success)} icon components`);
|
|
1241
|
-
const watchPath =
|
|
1343
|
+
const watchPath = path6.join(config.input, "**/*.svg");
|
|
1242
1344
|
const debounce = config.watch?.debounce ?? 300;
|
|
1243
1345
|
const ignore = config.watch?.ignore ?? ["**/node_modules/**", "**/.git/**"];
|
|
1244
1346
|
console.log(chalk3.bold("\nWatching for changes..."));
|
|
@@ -1256,7 +1358,7 @@ async function watch(options = {}) {
|
|
|
1256
1358
|
}).on("change", (filePath) => {
|
|
1257
1359
|
handleChange("changed", filePath, config, debounce, debounceTimer);
|
|
1258
1360
|
}).on("unlink", (filePath) => {
|
|
1259
|
-
console.log(chalk3.yellow(`SVG file removed: ${
|
|
1361
|
+
console.log(chalk3.yellow(`SVG file removed: ${path6.basename(filePath)}`));
|
|
1260
1362
|
handleChange("removed", filePath, config, debounce, debounceTimer);
|
|
1261
1363
|
}).on("error", (error) => {
|
|
1262
1364
|
console.error(chalk3.red(`Watcher error: ${error.message}`));
|
|
@@ -1275,7 +1377,7 @@ ${chalk3.yellow("Stopping watch mode...")}`);
|
|
|
1275
1377
|
}
|
|
1276
1378
|
}
|
|
1277
1379
|
function handleChange(event, filePath, config, debounce, timer) {
|
|
1278
|
-
const fileName =
|
|
1380
|
+
const fileName = path6.basename(filePath);
|
|
1279
1381
|
if (timer) {
|
|
1280
1382
|
clearTimeout(timer);
|
|
1281
1383
|
}
|
package/dist/cli.js
CHANGED
|
@@ -103,23 +103,23 @@ async function writeFile(filePath, content) {
|
|
|
103
103
|
}
|
|
104
104
|
async function getSvgFiles(dirPath) {
|
|
105
105
|
const fs2 = await import("fs/promises");
|
|
106
|
-
const
|
|
106
|
+
const path7 = await import("path");
|
|
107
107
|
try {
|
|
108
108
|
const files = await fs2.readdir(dirPath);
|
|
109
|
-
return files.filter((file) => file.endsWith(".svg")).map((file) =>
|
|
109
|
+
return files.filter((file) => file.endsWith(".svg")).map((file) => path7.join(dirPath, file));
|
|
110
110
|
} catch {
|
|
111
111
|
return [];
|
|
112
112
|
}
|
|
113
113
|
}
|
|
114
114
|
async function findProjectRoot(startDir = process.cwd()) {
|
|
115
|
-
const
|
|
115
|
+
const path7 = await import("path");
|
|
116
116
|
let currentDir = startDir;
|
|
117
117
|
while (true) {
|
|
118
|
-
const packageJsonPath =
|
|
118
|
+
const packageJsonPath = path7.join(currentDir, "package.json");
|
|
119
119
|
if (await fileExists(packageJsonPath)) {
|
|
120
120
|
return currentDir;
|
|
121
121
|
}
|
|
122
|
-
const parentDir =
|
|
122
|
+
const parentDir = path7.dirname(currentDir);
|
|
123
123
|
if (parentDir === currentDir) {
|
|
124
124
|
return startDir;
|
|
125
125
|
}
|
|
@@ -134,7 +134,7 @@ var init_helpers = __esm({
|
|
|
134
134
|
|
|
135
135
|
// src/cli.ts
|
|
136
136
|
var import_node_fs2 = require("fs");
|
|
137
|
-
var
|
|
137
|
+
var import_node_path7 = require("path");
|
|
138
138
|
var import_node_url2 = require("url");
|
|
139
139
|
var import_chalk4 = __toESM(require("chalk"));
|
|
140
140
|
var import_commander = require("commander");
|
|
@@ -777,7 +777,7 @@ async function findConfig() {
|
|
|
777
777
|
}
|
|
778
778
|
|
|
779
779
|
// src/generators/index.ts
|
|
780
|
-
var
|
|
780
|
+
var import_node_path4 = __toESM(require("path"));
|
|
781
781
|
|
|
782
782
|
// src/parsers/optimizer.ts
|
|
783
783
|
var import_svgo = require("svgo");
|
|
@@ -811,6 +811,101 @@ async function optimizeSvg(svgContent, config) {
|
|
|
811
811
|
}
|
|
812
812
|
}
|
|
813
813
|
|
|
814
|
+
// src/utils/formatter.ts
|
|
815
|
+
var import_node_child_process = require("child_process");
|
|
816
|
+
var import_node_path3 = __toESM(require("path"));
|
|
817
|
+
var import_node_process2 = __toESM(require("process"));
|
|
818
|
+
var import_node_util = require("util");
|
|
819
|
+
init_helpers();
|
|
820
|
+
var execAsync = (0, import_node_util.promisify)(import_node_child_process.exec);
|
|
821
|
+
var FORMATTER_PATTERNS = {
|
|
822
|
+
biome: ["biome.json", "biome.jsonc"],
|
|
823
|
+
prettier: [
|
|
824
|
+
".prettierrc",
|
|
825
|
+
".prettierrc.json",
|
|
826
|
+
".prettierrc.yml",
|
|
827
|
+
".prettierrc.yaml",
|
|
828
|
+
".prettierrc.js",
|
|
829
|
+
".prettierrc.cjs",
|
|
830
|
+
".prettierrc.mjs",
|
|
831
|
+
"prettier.config.js",
|
|
832
|
+
"prettier.config.cjs",
|
|
833
|
+
"prettier.config.mjs"
|
|
834
|
+
],
|
|
835
|
+
eslint: [
|
|
836
|
+
"eslint.config.js",
|
|
837
|
+
"eslint.config.mjs",
|
|
838
|
+
"eslint.config.cjs",
|
|
839
|
+
"eslint.config.ts",
|
|
840
|
+
".eslintrc",
|
|
841
|
+
".eslintrc.js",
|
|
842
|
+
".eslintrc.cjs",
|
|
843
|
+
".eslintrc.json",
|
|
844
|
+
".eslintrc.yml",
|
|
845
|
+
".eslintrc.yaml"
|
|
846
|
+
]
|
|
847
|
+
};
|
|
848
|
+
var FORMATTER_COMMANDS = {
|
|
849
|
+
biome: (outputDir, args) => `npx @biomejs/biome format --write ${args || ""} "${outputDir}"`.trim(),
|
|
850
|
+
prettier: (outputDir, args) => `npx prettier --write ${args || ""} "${outputDir}"`.trim(),
|
|
851
|
+
eslint: (outputDir, args) => `npx eslint --fix ${args || ""} "${outputDir}"`.trim()
|
|
852
|
+
};
|
|
853
|
+
function normalizeFormatOption(format) {
|
|
854
|
+
if (format === false) {
|
|
855
|
+
return null;
|
|
856
|
+
}
|
|
857
|
+
if (format === true) {
|
|
858
|
+
return { tool: "auto" };
|
|
859
|
+
}
|
|
860
|
+
if (typeof format === "string") {
|
|
861
|
+
return { tool: format };
|
|
862
|
+
}
|
|
863
|
+
return format;
|
|
864
|
+
}
|
|
865
|
+
async function detectFormatter() {
|
|
866
|
+
const cwd = import_node_process2.default.cwd();
|
|
867
|
+
const priority = ["biome", "prettier", "eslint"];
|
|
868
|
+
for (const tool of priority) {
|
|
869
|
+
const patterns = FORMATTER_PATTERNS[tool];
|
|
870
|
+
for (const pattern of patterns) {
|
|
871
|
+
const configPath = import_node_path3.default.join(cwd, pattern);
|
|
872
|
+
if (await fileExists(configPath)) {
|
|
873
|
+
return tool;
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
return null;
|
|
878
|
+
}
|
|
879
|
+
async function formatOutput(outputDir, format) {
|
|
880
|
+
const config = normalizeFormatOption(format);
|
|
881
|
+
if (!config) {
|
|
882
|
+
return { success: true };
|
|
883
|
+
}
|
|
884
|
+
let tool = null;
|
|
885
|
+
if (config.tool === "auto") {
|
|
886
|
+
tool = await detectFormatter();
|
|
887
|
+
if (!tool) {
|
|
888
|
+
return {
|
|
889
|
+
success: true,
|
|
890
|
+
error: "No formatter detected. Install prettier, eslint, or biome to enable auto-formatting."
|
|
891
|
+
};
|
|
892
|
+
}
|
|
893
|
+
} else {
|
|
894
|
+
tool = config.tool || "prettier";
|
|
895
|
+
}
|
|
896
|
+
const command = FORMATTER_COMMANDS[tool](outputDir, config.args);
|
|
897
|
+
try {
|
|
898
|
+
await execAsync(command, { cwd: import_node_process2.default.cwd() });
|
|
899
|
+
return { success: true, tool };
|
|
900
|
+
} catch (error) {
|
|
901
|
+
return {
|
|
902
|
+
success: false,
|
|
903
|
+
tool,
|
|
904
|
+
error: `Format failed with ${tool}: ${error.message}`
|
|
905
|
+
};
|
|
906
|
+
}
|
|
907
|
+
}
|
|
908
|
+
|
|
814
909
|
// src/generators/index.ts
|
|
815
910
|
init_helpers();
|
|
816
911
|
async function generateIcons(config, dryRun = false) {
|
|
@@ -853,6 +948,14 @@ async function generateIcons(config, dryRun = false) {
|
|
|
853
948
|
if (config.generateOptions?.preview && !dryRun) {
|
|
854
949
|
await generatePreviewHtml(svgFiles, config);
|
|
855
950
|
}
|
|
951
|
+
if (config.format && !dryRun) {
|
|
952
|
+
const formatResult = await formatOutput(config.output, config.format);
|
|
953
|
+
if (formatResult.success && formatResult.tool) {
|
|
954
|
+
console.log(`Formatted with ${formatResult.tool}`);
|
|
955
|
+
} else if (formatResult.error) {
|
|
956
|
+
console.warn(formatResult.error);
|
|
957
|
+
}
|
|
958
|
+
}
|
|
856
959
|
if (config.hooks?.onComplete) {
|
|
857
960
|
await config.hooks.onComplete(stats);
|
|
858
961
|
}
|
|
@@ -863,7 +966,7 @@ async function generateIcons(config, dryRun = false) {
|
|
|
863
966
|
}
|
|
864
967
|
async function generateIconComponent(svgFile, config, dryRun = false) {
|
|
865
968
|
let svgContent = await readFile(svgFile);
|
|
866
|
-
const fileName =
|
|
969
|
+
const fileName = import_node_path4.default.basename(svgFile);
|
|
867
970
|
if (config.hooks?.beforeParse) {
|
|
868
971
|
svgContent = await config.hooks.beforeParse(svgContent, fileName);
|
|
869
972
|
}
|
|
@@ -887,7 +990,7 @@ async function generateIconComponent(svgFile, config, dryRun = false) {
|
|
|
887
990
|
code = await config.hooks.afterGenerate(code, componentName);
|
|
888
991
|
}
|
|
889
992
|
const fileExt = strategy.getComponentExtension(typescript);
|
|
890
|
-
const outputPath =
|
|
993
|
+
const outputPath = import_node_path4.default.join(config.output, `${componentName}.${fileExt}`);
|
|
891
994
|
if (dryRun) {
|
|
892
995
|
console.log(` ${componentName}.${fileExt}`);
|
|
893
996
|
} else {
|
|
@@ -898,7 +1001,7 @@ async function generateBaseComponent(config, dryRun = false) {
|
|
|
898
1001
|
const typescript = config.typescript ?? true;
|
|
899
1002
|
const strategy = getFrameworkStrategy(config.framework);
|
|
900
1003
|
const { code, fileName } = strategy.generateBaseComponent(typescript);
|
|
901
|
-
const outputPath =
|
|
1004
|
+
const outputPath = import_node_path4.default.join(config.output, fileName);
|
|
902
1005
|
if (dryRun) {
|
|
903
1006
|
console.log(` ${fileName}`);
|
|
904
1007
|
} else {
|
|
@@ -911,7 +1014,7 @@ async function generateIndexFile(svgFiles, config, dryRun = false) {
|
|
|
911
1014
|
const ext = strategy.getIndexExtension(typescript);
|
|
912
1015
|
const usesDefaultExport = ["vue", "svelte", "react", "preact"].includes(config.framework);
|
|
913
1016
|
const exports2 = svgFiles.map((svgFile) => {
|
|
914
|
-
const fileName =
|
|
1017
|
+
const fileName = import_node_path4.default.basename(svgFile);
|
|
915
1018
|
const componentName = getComponentName(
|
|
916
1019
|
fileName,
|
|
917
1020
|
config.prefix,
|
|
@@ -924,7 +1027,7 @@ async function generateIndexFile(svgFiles, config, dryRun = false) {
|
|
|
924
1027
|
return `export { ${componentName} } from './${componentName}'`;
|
|
925
1028
|
}
|
|
926
1029
|
}).join("\n");
|
|
927
|
-
const indexPath =
|
|
1030
|
+
const indexPath = import_node_path4.default.join(config.output, `index.${ext}`);
|
|
928
1031
|
if (dryRun) {
|
|
929
1032
|
console.log(` index.${ext}`);
|
|
930
1033
|
} else {
|
|
@@ -934,7 +1037,7 @@ async function generateIndexFile(svgFiles, config, dryRun = false) {
|
|
|
934
1037
|
}
|
|
935
1038
|
async function generatePreviewHtml(svgFiles, config) {
|
|
936
1039
|
const componentNames = svgFiles.map((svgFile) => {
|
|
937
|
-
const fileName =
|
|
1040
|
+
const fileName = import_node_path4.default.basename(svgFile);
|
|
938
1041
|
return getComponentName(
|
|
939
1042
|
fileName,
|
|
940
1043
|
config.prefix,
|
|
@@ -1106,7 +1209,7 @@ async function generatePreviewHtml(svgFiles, config) {
|
|
|
1106
1209
|
</script>
|
|
1107
1210
|
</body>
|
|
1108
1211
|
</html>`;
|
|
1109
|
-
const previewPath =
|
|
1212
|
+
const previewPath = import_node_path4.default.join(config.output, "preview.html");
|
|
1110
1213
|
await writeFile(previewPath, html);
|
|
1111
1214
|
}
|
|
1112
1215
|
async function cleanOutputDirectory(svgFiles, config) {
|
|
@@ -1115,7 +1218,7 @@ async function cleanOutputDirectory(svgFiles, config) {
|
|
|
1115
1218
|
const fileExt = strategy.getComponentExtension(config.typescript ?? true);
|
|
1116
1219
|
const expectedComponents = new Set(
|
|
1117
1220
|
svgFiles.map((svgFile) => {
|
|
1118
|
-
const fileName =
|
|
1221
|
+
const fileName = import_node_path4.default.basename(svgFile, ".svg");
|
|
1119
1222
|
const componentName = getComponentName(
|
|
1120
1223
|
fileName,
|
|
1121
1224
|
config.prefix,
|
|
@@ -1142,7 +1245,7 @@ async function cleanOutputDirectory(svgFiles, config) {
|
|
|
1142
1245
|
continue;
|
|
1143
1246
|
}
|
|
1144
1247
|
if (!expectedComponents.has(file)) {
|
|
1145
|
-
const filePath =
|
|
1248
|
+
const filePath = import_node_path4.default.join(config.output, file);
|
|
1146
1249
|
await unlink(filePath);
|
|
1147
1250
|
console.log(`Deleted orphaned component: ${file}`);
|
|
1148
1251
|
}
|
|
@@ -1209,8 +1312,8 @@ ${import_chalk.default.bold("Output:")} ${import_chalk.default.cyan(config.outpu
|
|
|
1209
1312
|
}
|
|
1210
1313
|
|
|
1211
1314
|
// src/commands/init.ts
|
|
1212
|
-
var
|
|
1213
|
-
var
|
|
1315
|
+
var import_node_path5 = __toESM(require("path"));
|
|
1316
|
+
var import_node_process3 = __toESM(require("process"));
|
|
1214
1317
|
var import_chalk2 = __toESM(require("chalk"));
|
|
1215
1318
|
var import_inquirer = __toESM(require("inquirer"));
|
|
1216
1319
|
var import_ora2 = __toESM(require("ora"));
|
|
@@ -1218,7 +1321,7 @@ init_helpers();
|
|
|
1218
1321
|
async function init(options = {}) {
|
|
1219
1322
|
try {
|
|
1220
1323
|
const projectRoot = await findProjectRoot();
|
|
1221
|
-
const currentDir =
|
|
1324
|
+
const currentDir = import_node_process3.default.cwd();
|
|
1222
1325
|
if (currentDir !== projectRoot) {
|
|
1223
1326
|
console.log(import_chalk2.default.yellow(`
|
|
1224
1327
|
Note: Project root detected at ${import_chalk2.default.cyan(projectRoot)}`));
|
|
@@ -1239,8 +1342,8 @@ Note: Project root detected at ${import_chalk2.default.cyan(projectRoot)}`));
|
|
|
1239
1342
|
}
|
|
1240
1343
|
}
|
|
1241
1344
|
]);
|
|
1242
|
-
const configPath =
|
|
1243
|
-
const configDir =
|
|
1345
|
+
const configPath = import_node_path5.default.resolve(projectRoot, pathAnswers.configPath);
|
|
1346
|
+
const configDir = import_node_path5.default.dirname(configPath);
|
|
1244
1347
|
if (!options.force && await fileExists(configPath)) {
|
|
1245
1348
|
const { overwrite } = await import_inquirer.default.prompt([
|
|
1246
1349
|
{
|
|
@@ -1304,14 +1407,14 @@ Note: Project root detected at ${import_chalk2.default.cyan(projectRoot)}`));
|
|
|
1304
1407
|
default: ""
|
|
1305
1408
|
}
|
|
1306
1409
|
]);
|
|
1307
|
-
const inputPath =
|
|
1308
|
-
const outputPath =
|
|
1410
|
+
const inputPath = import_node_path5.default.resolve(projectRoot, answers.input);
|
|
1411
|
+
const outputPath = import_node_path5.default.resolve(projectRoot, answers.output);
|
|
1309
1412
|
const spinner = (0, import_ora2.default)("Setting up directories...").start();
|
|
1310
1413
|
await ensureDir(inputPath);
|
|
1311
1414
|
spinner.text = `Created input directory: ${import_chalk2.default.cyan(answers.input)}`;
|
|
1312
1415
|
await ensureDir(outputPath);
|
|
1313
1416
|
spinner.succeed(`Created output directory: ${import_chalk2.default.cyan(answers.output)}`);
|
|
1314
|
-
const relativeConfigDir =
|
|
1417
|
+
const relativeConfigDir = import_node_path5.default.relative(configDir, projectRoot) || ".";
|
|
1315
1418
|
const configContent = generateConfigContent(answers, relativeConfigDir);
|
|
1316
1419
|
spinner.start("Creating config file...");
|
|
1317
1420
|
await writeFile(configPath, configContent);
|
|
@@ -1354,7 +1457,7 @@ export default defineConfig({
|
|
|
1354
1457
|
}
|
|
1355
1458
|
|
|
1356
1459
|
// src/commands/watch.ts
|
|
1357
|
-
var
|
|
1460
|
+
var import_node_path6 = __toESM(require("path"));
|
|
1358
1461
|
var import_chalk3 = __toESM(require("chalk"));
|
|
1359
1462
|
var import_chokidar = __toESM(require("chokidar"));
|
|
1360
1463
|
var import_ora3 = __toESM(require("ora"));
|
|
@@ -1376,7 +1479,7 @@ async function watch(options = {}) {
|
|
|
1376
1479
|
spinner.start("Generating icon components...");
|
|
1377
1480
|
const initialStats = await generateIcons(config);
|
|
1378
1481
|
spinner.succeed(`Generated ${import_chalk3.default.green(initialStats.success)} icon components`);
|
|
1379
|
-
const watchPath =
|
|
1482
|
+
const watchPath = import_node_path6.default.join(config.input, "**/*.svg");
|
|
1380
1483
|
const debounce = config.watch?.debounce ?? 300;
|
|
1381
1484
|
const ignore = config.watch?.ignore ?? ["**/node_modules/**", "**/.git/**"];
|
|
1382
1485
|
console.log(import_chalk3.default.bold("\nWatching for changes..."));
|
|
@@ -1394,7 +1497,7 @@ async function watch(options = {}) {
|
|
|
1394
1497
|
}).on("change", (filePath) => {
|
|
1395
1498
|
handleChange("changed", filePath, config, debounce, debounceTimer);
|
|
1396
1499
|
}).on("unlink", (filePath) => {
|
|
1397
|
-
console.log(import_chalk3.default.yellow(`SVG file removed: ${
|
|
1500
|
+
console.log(import_chalk3.default.yellow(`SVG file removed: ${import_node_path6.default.basename(filePath)}`));
|
|
1398
1501
|
handleChange("removed", filePath, config, debounce, debounceTimer);
|
|
1399
1502
|
}).on("error", (error) => {
|
|
1400
1503
|
console.error(import_chalk3.default.red(`Watcher error: ${error.message}`));
|
|
@@ -1413,7 +1516,7 @@ ${import_chalk3.default.yellow("Stopping watch mode...")}`);
|
|
|
1413
1516
|
}
|
|
1414
1517
|
}
|
|
1415
1518
|
function handleChange(event, filePath, config, debounce, timer) {
|
|
1416
|
-
const fileName =
|
|
1519
|
+
const fileName = import_node_path6.default.basename(filePath);
|
|
1417
1520
|
if (timer) {
|
|
1418
1521
|
clearTimeout(timer);
|
|
1419
1522
|
}
|
|
@@ -1442,11 +1545,11 @@ var import_meta2 = {};
|
|
|
1442
1545
|
function getPackageJson() {
|
|
1443
1546
|
let pkgPath;
|
|
1444
1547
|
if (typeof __dirname !== "undefined") {
|
|
1445
|
-
pkgPath = (0,
|
|
1548
|
+
pkgPath = (0, import_node_path7.join)(__dirname, "../package.json");
|
|
1446
1549
|
} else {
|
|
1447
1550
|
const __filename = (0, import_node_url2.fileURLToPath)(import_meta2.url);
|
|
1448
|
-
const __dirname2 = (0,
|
|
1449
|
-
pkgPath = (0,
|
|
1551
|
+
const __dirname2 = (0, import_node_path7.dirname)(__filename);
|
|
1552
|
+
pkgPath = (0, import_node_path7.join)(__dirname2, "../package.json");
|
|
1450
1553
|
}
|
|
1451
1554
|
return JSON.parse((0, import_node_fs2.readFileSync)(pkgPath, "utf-8"));
|
|
1452
1555
|
}
|
package/dist/cli.mjs
CHANGED
package/dist/index.d.mts
CHANGED
|
@@ -54,6 +54,33 @@ interface IconProps {
|
|
|
54
54
|
* Framework types supported
|
|
55
55
|
*/
|
|
56
56
|
type Framework = 'react' | 'vue' | 'svelte' | 'solid' | 'preact' | 'lit' | 'angular' | 'qwik' | 'astro' | 'vanilla';
|
|
57
|
+
/**
|
|
58
|
+
* Formatter tool types
|
|
59
|
+
*/
|
|
60
|
+
type FormatterTool = 'auto' | 'prettier' | 'eslint' | 'biome';
|
|
61
|
+
/**
|
|
62
|
+
* Format configuration
|
|
63
|
+
*/
|
|
64
|
+
interface FormatConfig {
|
|
65
|
+
/**
|
|
66
|
+
* Formatter tool to use
|
|
67
|
+
* - 'auto': Auto-detect based on project config files
|
|
68
|
+
* - 'prettier': Use Prettier
|
|
69
|
+
* - 'eslint': Use ESLint --fix
|
|
70
|
+
* - 'biome': Use Biome
|
|
71
|
+
* @default 'auto'
|
|
72
|
+
*/
|
|
73
|
+
tool?: FormatterTool;
|
|
74
|
+
/**
|
|
75
|
+
* Additional arguments to pass to the formatter
|
|
76
|
+
* @example '--single-quote'
|
|
77
|
+
*/
|
|
78
|
+
args?: string;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Format option type (shorthand or full config)
|
|
82
|
+
*/
|
|
83
|
+
type FormatOption = boolean | FormatterTool | FormatConfig;
|
|
57
84
|
/**
|
|
58
85
|
* Main configuration interface
|
|
59
86
|
*/
|
|
@@ -169,6 +196,15 @@ interface IconForgeConfig {
|
|
|
169
196
|
*/
|
|
170
197
|
debounce?: number;
|
|
171
198
|
};
|
|
199
|
+
/**
|
|
200
|
+
* Format generated files after generation
|
|
201
|
+
* - true: Auto-detect formatter (biome > prettier > eslint)
|
|
202
|
+
* - false: Disable formatting
|
|
203
|
+
* - 'prettier' | 'eslint' | 'biome': Use specific formatter
|
|
204
|
+
* - { tool: 'auto', args: '--single-quote' }: Full config
|
|
205
|
+
* @default false
|
|
206
|
+
*/
|
|
207
|
+
format?: FormatOption;
|
|
172
208
|
/**
|
|
173
209
|
* Lifecycle hooks
|
|
174
210
|
*/
|
|
@@ -278,4 +314,4 @@ declare const frameworkRegistry: FrameworkRegistry;
|
|
|
278
314
|
*/
|
|
279
315
|
declare function getFrameworkStrategy(framework: Framework): FrameworkStrategy;
|
|
280
316
|
|
|
281
|
-
export { type Framework, type FrameworkStrategy, type GenerationStats, type IconForgeConfig, type IconNode, type IconProps, type SVGElementType, defineConfig, findConfig, frameworkRegistry, generate, generateIcons, getFrameworkStrategy, init, loadConfig, watch };
|
|
317
|
+
export { type FormatConfig, type FormatOption, type FormatterTool, type Framework, type FrameworkStrategy, type GenerationStats, type IconForgeConfig, type IconNode, type IconProps, type SVGElementType, defineConfig, findConfig, frameworkRegistry, generate, generateIcons, getFrameworkStrategy, init, loadConfig, watch };
|
package/dist/index.d.ts
CHANGED
|
@@ -54,6 +54,33 @@ interface IconProps {
|
|
|
54
54
|
* Framework types supported
|
|
55
55
|
*/
|
|
56
56
|
type Framework = 'react' | 'vue' | 'svelte' | 'solid' | 'preact' | 'lit' | 'angular' | 'qwik' | 'astro' | 'vanilla';
|
|
57
|
+
/**
|
|
58
|
+
* Formatter tool types
|
|
59
|
+
*/
|
|
60
|
+
type FormatterTool = 'auto' | 'prettier' | 'eslint' | 'biome';
|
|
61
|
+
/**
|
|
62
|
+
* Format configuration
|
|
63
|
+
*/
|
|
64
|
+
interface FormatConfig {
|
|
65
|
+
/**
|
|
66
|
+
* Formatter tool to use
|
|
67
|
+
* - 'auto': Auto-detect based on project config files
|
|
68
|
+
* - 'prettier': Use Prettier
|
|
69
|
+
* - 'eslint': Use ESLint --fix
|
|
70
|
+
* - 'biome': Use Biome
|
|
71
|
+
* @default 'auto'
|
|
72
|
+
*/
|
|
73
|
+
tool?: FormatterTool;
|
|
74
|
+
/**
|
|
75
|
+
* Additional arguments to pass to the formatter
|
|
76
|
+
* @example '--single-quote'
|
|
77
|
+
*/
|
|
78
|
+
args?: string;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Format option type (shorthand or full config)
|
|
82
|
+
*/
|
|
83
|
+
type FormatOption = boolean | FormatterTool | FormatConfig;
|
|
57
84
|
/**
|
|
58
85
|
* Main configuration interface
|
|
59
86
|
*/
|
|
@@ -169,6 +196,15 @@ interface IconForgeConfig {
|
|
|
169
196
|
*/
|
|
170
197
|
debounce?: number;
|
|
171
198
|
};
|
|
199
|
+
/**
|
|
200
|
+
* Format generated files after generation
|
|
201
|
+
* - true: Auto-detect formatter (biome > prettier > eslint)
|
|
202
|
+
* - false: Disable formatting
|
|
203
|
+
* - 'prettier' | 'eslint' | 'biome': Use specific formatter
|
|
204
|
+
* - { tool: 'auto', args: '--single-quote' }: Full config
|
|
205
|
+
* @default false
|
|
206
|
+
*/
|
|
207
|
+
format?: FormatOption;
|
|
172
208
|
/**
|
|
173
209
|
* Lifecycle hooks
|
|
174
210
|
*/
|
|
@@ -278,4 +314,4 @@ declare const frameworkRegistry: FrameworkRegistry;
|
|
|
278
314
|
*/
|
|
279
315
|
declare function getFrameworkStrategy(framework: Framework): FrameworkStrategy;
|
|
280
316
|
|
|
281
|
-
export { type Framework, type FrameworkStrategy, type GenerationStats, type IconForgeConfig, type IconNode, type IconProps, type SVGElementType, defineConfig, findConfig, frameworkRegistry, generate, generateIcons, getFrameworkStrategy, init, loadConfig, watch };
|
|
317
|
+
export { type FormatConfig, type FormatOption, type FormatterTool, type Framework, type FrameworkStrategy, type GenerationStats, type IconForgeConfig, type IconNode, type IconProps, type SVGElementType, defineConfig, findConfig, frameworkRegistry, generate, generateIcons, getFrameworkStrategy, init, loadConfig, watch };
|
package/dist/index.js
CHANGED
|
@@ -103,23 +103,23 @@ async function writeFile(filePath, content) {
|
|
|
103
103
|
}
|
|
104
104
|
async function getSvgFiles(dirPath) {
|
|
105
105
|
const fs2 = await import("fs/promises");
|
|
106
|
-
const
|
|
106
|
+
const path7 = await import("path");
|
|
107
107
|
try {
|
|
108
108
|
const files = await fs2.readdir(dirPath);
|
|
109
|
-
return files.filter((file) => file.endsWith(".svg")).map((file) =>
|
|
109
|
+
return files.filter((file) => file.endsWith(".svg")).map((file) => path7.join(dirPath, file));
|
|
110
110
|
} catch {
|
|
111
111
|
return [];
|
|
112
112
|
}
|
|
113
113
|
}
|
|
114
114
|
async function findProjectRoot(startDir = process.cwd()) {
|
|
115
|
-
const
|
|
115
|
+
const path7 = await import("path");
|
|
116
116
|
let currentDir = startDir;
|
|
117
117
|
while (true) {
|
|
118
|
-
const packageJsonPath =
|
|
118
|
+
const packageJsonPath = path7.join(currentDir, "package.json");
|
|
119
119
|
if (await fileExists(packageJsonPath)) {
|
|
120
120
|
return currentDir;
|
|
121
121
|
}
|
|
122
|
-
const parentDir =
|
|
122
|
+
const parentDir = path7.dirname(currentDir);
|
|
123
123
|
if (parentDir === currentDir) {
|
|
124
124
|
return startDir;
|
|
125
125
|
}
|
|
@@ -785,7 +785,7 @@ async function findConfig() {
|
|
|
785
785
|
}
|
|
786
786
|
|
|
787
787
|
// src/generators/index.ts
|
|
788
|
-
var
|
|
788
|
+
var import_node_path4 = __toESM(require("path"));
|
|
789
789
|
|
|
790
790
|
// src/parsers/optimizer.ts
|
|
791
791
|
var import_svgo = require("svgo");
|
|
@@ -819,6 +819,101 @@ async function optimizeSvg(svgContent, config) {
|
|
|
819
819
|
}
|
|
820
820
|
}
|
|
821
821
|
|
|
822
|
+
// src/utils/formatter.ts
|
|
823
|
+
var import_node_child_process = require("child_process");
|
|
824
|
+
var import_node_path3 = __toESM(require("path"));
|
|
825
|
+
var import_node_process2 = __toESM(require("process"));
|
|
826
|
+
var import_node_util = require("util");
|
|
827
|
+
init_helpers();
|
|
828
|
+
var execAsync = (0, import_node_util.promisify)(import_node_child_process.exec);
|
|
829
|
+
var FORMATTER_PATTERNS = {
|
|
830
|
+
biome: ["biome.json", "biome.jsonc"],
|
|
831
|
+
prettier: [
|
|
832
|
+
".prettierrc",
|
|
833
|
+
".prettierrc.json",
|
|
834
|
+
".prettierrc.yml",
|
|
835
|
+
".prettierrc.yaml",
|
|
836
|
+
".prettierrc.js",
|
|
837
|
+
".prettierrc.cjs",
|
|
838
|
+
".prettierrc.mjs",
|
|
839
|
+
"prettier.config.js",
|
|
840
|
+
"prettier.config.cjs",
|
|
841
|
+
"prettier.config.mjs"
|
|
842
|
+
],
|
|
843
|
+
eslint: [
|
|
844
|
+
"eslint.config.js",
|
|
845
|
+
"eslint.config.mjs",
|
|
846
|
+
"eslint.config.cjs",
|
|
847
|
+
"eslint.config.ts",
|
|
848
|
+
".eslintrc",
|
|
849
|
+
".eslintrc.js",
|
|
850
|
+
".eslintrc.cjs",
|
|
851
|
+
".eslintrc.json",
|
|
852
|
+
".eslintrc.yml",
|
|
853
|
+
".eslintrc.yaml"
|
|
854
|
+
]
|
|
855
|
+
};
|
|
856
|
+
var FORMATTER_COMMANDS = {
|
|
857
|
+
biome: (outputDir, args) => `npx @biomejs/biome format --write ${args || ""} "${outputDir}"`.trim(),
|
|
858
|
+
prettier: (outputDir, args) => `npx prettier --write ${args || ""} "${outputDir}"`.trim(),
|
|
859
|
+
eslint: (outputDir, args) => `npx eslint --fix ${args || ""} "${outputDir}"`.trim()
|
|
860
|
+
};
|
|
861
|
+
function normalizeFormatOption(format) {
|
|
862
|
+
if (format === false) {
|
|
863
|
+
return null;
|
|
864
|
+
}
|
|
865
|
+
if (format === true) {
|
|
866
|
+
return { tool: "auto" };
|
|
867
|
+
}
|
|
868
|
+
if (typeof format === "string") {
|
|
869
|
+
return { tool: format };
|
|
870
|
+
}
|
|
871
|
+
return format;
|
|
872
|
+
}
|
|
873
|
+
async function detectFormatter() {
|
|
874
|
+
const cwd = import_node_process2.default.cwd();
|
|
875
|
+
const priority = ["biome", "prettier", "eslint"];
|
|
876
|
+
for (const tool of priority) {
|
|
877
|
+
const patterns = FORMATTER_PATTERNS[tool];
|
|
878
|
+
for (const pattern of patterns) {
|
|
879
|
+
const configPath = import_node_path3.default.join(cwd, pattern);
|
|
880
|
+
if (await fileExists(configPath)) {
|
|
881
|
+
return tool;
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
return null;
|
|
886
|
+
}
|
|
887
|
+
async function formatOutput(outputDir, format) {
|
|
888
|
+
const config = normalizeFormatOption(format);
|
|
889
|
+
if (!config) {
|
|
890
|
+
return { success: true };
|
|
891
|
+
}
|
|
892
|
+
let tool = null;
|
|
893
|
+
if (config.tool === "auto") {
|
|
894
|
+
tool = await detectFormatter();
|
|
895
|
+
if (!tool) {
|
|
896
|
+
return {
|
|
897
|
+
success: true,
|
|
898
|
+
error: "No formatter detected. Install prettier, eslint, or biome to enable auto-formatting."
|
|
899
|
+
};
|
|
900
|
+
}
|
|
901
|
+
} else {
|
|
902
|
+
tool = config.tool || "prettier";
|
|
903
|
+
}
|
|
904
|
+
const command = FORMATTER_COMMANDS[tool](outputDir, config.args);
|
|
905
|
+
try {
|
|
906
|
+
await execAsync(command, { cwd: import_node_process2.default.cwd() });
|
|
907
|
+
return { success: true, tool };
|
|
908
|
+
} catch (error) {
|
|
909
|
+
return {
|
|
910
|
+
success: false,
|
|
911
|
+
tool,
|
|
912
|
+
error: `Format failed with ${tool}: ${error.message}`
|
|
913
|
+
};
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
|
|
822
917
|
// src/generators/index.ts
|
|
823
918
|
init_helpers();
|
|
824
919
|
async function generateIcons(config, dryRun = false) {
|
|
@@ -861,6 +956,14 @@ async function generateIcons(config, dryRun = false) {
|
|
|
861
956
|
if (config.generateOptions?.preview && !dryRun) {
|
|
862
957
|
await generatePreviewHtml(svgFiles, config);
|
|
863
958
|
}
|
|
959
|
+
if (config.format && !dryRun) {
|
|
960
|
+
const formatResult = await formatOutput(config.output, config.format);
|
|
961
|
+
if (formatResult.success && formatResult.tool) {
|
|
962
|
+
console.log(`Formatted with ${formatResult.tool}`);
|
|
963
|
+
} else if (formatResult.error) {
|
|
964
|
+
console.warn(formatResult.error);
|
|
965
|
+
}
|
|
966
|
+
}
|
|
864
967
|
if (config.hooks?.onComplete) {
|
|
865
968
|
await config.hooks.onComplete(stats);
|
|
866
969
|
}
|
|
@@ -871,7 +974,7 @@ async function generateIcons(config, dryRun = false) {
|
|
|
871
974
|
}
|
|
872
975
|
async function generateIconComponent(svgFile, config, dryRun = false) {
|
|
873
976
|
let svgContent = await readFile(svgFile);
|
|
874
|
-
const fileName =
|
|
977
|
+
const fileName = import_node_path4.default.basename(svgFile);
|
|
875
978
|
if (config.hooks?.beforeParse) {
|
|
876
979
|
svgContent = await config.hooks.beforeParse(svgContent, fileName);
|
|
877
980
|
}
|
|
@@ -895,7 +998,7 @@ async function generateIconComponent(svgFile, config, dryRun = false) {
|
|
|
895
998
|
code = await config.hooks.afterGenerate(code, componentName);
|
|
896
999
|
}
|
|
897
1000
|
const fileExt = strategy.getComponentExtension(typescript);
|
|
898
|
-
const outputPath =
|
|
1001
|
+
const outputPath = import_node_path4.default.join(config.output, `${componentName}.${fileExt}`);
|
|
899
1002
|
if (dryRun) {
|
|
900
1003
|
console.log(` ${componentName}.${fileExt}`);
|
|
901
1004
|
} else {
|
|
@@ -906,7 +1009,7 @@ async function generateBaseComponent(config, dryRun = false) {
|
|
|
906
1009
|
const typescript = config.typescript ?? true;
|
|
907
1010
|
const strategy = getFrameworkStrategy(config.framework);
|
|
908
1011
|
const { code, fileName } = strategy.generateBaseComponent(typescript);
|
|
909
|
-
const outputPath =
|
|
1012
|
+
const outputPath = import_node_path4.default.join(config.output, fileName);
|
|
910
1013
|
if (dryRun) {
|
|
911
1014
|
console.log(` ${fileName}`);
|
|
912
1015
|
} else {
|
|
@@ -919,7 +1022,7 @@ async function generateIndexFile(svgFiles, config, dryRun = false) {
|
|
|
919
1022
|
const ext = strategy.getIndexExtension(typescript);
|
|
920
1023
|
const usesDefaultExport = ["vue", "svelte", "react", "preact"].includes(config.framework);
|
|
921
1024
|
const exports2 = svgFiles.map((svgFile) => {
|
|
922
|
-
const fileName =
|
|
1025
|
+
const fileName = import_node_path4.default.basename(svgFile);
|
|
923
1026
|
const componentName = getComponentName(
|
|
924
1027
|
fileName,
|
|
925
1028
|
config.prefix,
|
|
@@ -932,7 +1035,7 @@ async function generateIndexFile(svgFiles, config, dryRun = false) {
|
|
|
932
1035
|
return `export { ${componentName} } from './${componentName}'`;
|
|
933
1036
|
}
|
|
934
1037
|
}).join("\n");
|
|
935
|
-
const indexPath =
|
|
1038
|
+
const indexPath = import_node_path4.default.join(config.output, `index.${ext}`);
|
|
936
1039
|
if (dryRun) {
|
|
937
1040
|
console.log(` index.${ext}`);
|
|
938
1041
|
} else {
|
|
@@ -942,7 +1045,7 @@ async function generateIndexFile(svgFiles, config, dryRun = false) {
|
|
|
942
1045
|
}
|
|
943
1046
|
async function generatePreviewHtml(svgFiles, config) {
|
|
944
1047
|
const componentNames = svgFiles.map((svgFile) => {
|
|
945
|
-
const fileName =
|
|
1048
|
+
const fileName = import_node_path4.default.basename(svgFile);
|
|
946
1049
|
return getComponentName(
|
|
947
1050
|
fileName,
|
|
948
1051
|
config.prefix,
|
|
@@ -1114,7 +1217,7 @@ async function generatePreviewHtml(svgFiles, config) {
|
|
|
1114
1217
|
</script>
|
|
1115
1218
|
</body>
|
|
1116
1219
|
</html>`;
|
|
1117
|
-
const previewPath =
|
|
1220
|
+
const previewPath = import_node_path4.default.join(config.output, "preview.html");
|
|
1118
1221
|
await writeFile(previewPath, html);
|
|
1119
1222
|
}
|
|
1120
1223
|
async function cleanOutputDirectory(svgFiles, config) {
|
|
@@ -1123,7 +1226,7 @@ async function cleanOutputDirectory(svgFiles, config) {
|
|
|
1123
1226
|
const fileExt = strategy.getComponentExtension(config.typescript ?? true);
|
|
1124
1227
|
const expectedComponents = new Set(
|
|
1125
1228
|
svgFiles.map((svgFile) => {
|
|
1126
|
-
const fileName =
|
|
1229
|
+
const fileName = import_node_path4.default.basename(svgFile, ".svg");
|
|
1127
1230
|
const componentName = getComponentName(
|
|
1128
1231
|
fileName,
|
|
1129
1232
|
config.prefix,
|
|
@@ -1150,7 +1253,7 @@ async function cleanOutputDirectory(svgFiles, config) {
|
|
|
1150
1253
|
continue;
|
|
1151
1254
|
}
|
|
1152
1255
|
if (!expectedComponents.has(file)) {
|
|
1153
|
-
const filePath =
|
|
1256
|
+
const filePath = import_node_path4.default.join(config.output, file);
|
|
1154
1257
|
await unlink(filePath);
|
|
1155
1258
|
console.log(`Deleted orphaned component: ${file}`);
|
|
1156
1259
|
}
|
|
@@ -1217,8 +1320,8 @@ ${import_chalk.default.bold("Output:")} ${import_chalk.default.cyan(config.outpu
|
|
|
1217
1320
|
}
|
|
1218
1321
|
|
|
1219
1322
|
// src/commands/init.ts
|
|
1220
|
-
var
|
|
1221
|
-
var
|
|
1323
|
+
var import_node_path5 = __toESM(require("path"));
|
|
1324
|
+
var import_node_process3 = __toESM(require("process"));
|
|
1222
1325
|
var import_chalk2 = __toESM(require("chalk"));
|
|
1223
1326
|
var import_inquirer = __toESM(require("inquirer"));
|
|
1224
1327
|
var import_ora2 = __toESM(require("ora"));
|
|
@@ -1226,7 +1329,7 @@ init_helpers();
|
|
|
1226
1329
|
async function init(options = {}) {
|
|
1227
1330
|
try {
|
|
1228
1331
|
const projectRoot = await findProjectRoot();
|
|
1229
|
-
const currentDir =
|
|
1332
|
+
const currentDir = import_node_process3.default.cwd();
|
|
1230
1333
|
if (currentDir !== projectRoot) {
|
|
1231
1334
|
console.log(import_chalk2.default.yellow(`
|
|
1232
1335
|
Note: Project root detected at ${import_chalk2.default.cyan(projectRoot)}`));
|
|
@@ -1247,8 +1350,8 @@ Note: Project root detected at ${import_chalk2.default.cyan(projectRoot)}`));
|
|
|
1247
1350
|
}
|
|
1248
1351
|
}
|
|
1249
1352
|
]);
|
|
1250
|
-
const configPath =
|
|
1251
|
-
const configDir =
|
|
1353
|
+
const configPath = import_node_path5.default.resolve(projectRoot, pathAnswers.configPath);
|
|
1354
|
+
const configDir = import_node_path5.default.dirname(configPath);
|
|
1252
1355
|
if (!options.force && await fileExists(configPath)) {
|
|
1253
1356
|
const { overwrite } = await import_inquirer.default.prompt([
|
|
1254
1357
|
{
|
|
@@ -1312,14 +1415,14 @@ Note: Project root detected at ${import_chalk2.default.cyan(projectRoot)}`));
|
|
|
1312
1415
|
default: ""
|
|
1313
1416
|
}
|
|
1314
1417
|
]);
|
|
1315
|
-
const inputPath =
|
|
1316
|
-
const outputPath =
|
|
1418
|
+
const inputPath = import_node_path5.default.resolve(projectRoot, answers.input);
|
|
1419
|
+
const outputPath = import_node_path5.default.resolve(projectRoot, answers.output);
|
|
1317
1420
|
const spinner = (0, import_ora2.default)("Setting up directories...").start();
|
|
1318
1421
|
await ensureDir(inputPath);
|
|
1319
1422
|
spinner.text = `Created input directory: ${import_chalk2.default.cyan(answers.input)}`;
|
|
1320
1423
|
await ensureDir(outputPath);
|
|
1321
1424
|
spinner.succeed(`Created output directory: ${import_chalk2.default.cyan(answers.output)}`);
|
|
1322
|
-
const relativeConfigDir =
|
|
1425
|
+
const relativeConfigDir = import_node_path5.default.relative(configDir, projectRoot) || ".";
|
|
1323
1426
|
const configContent = generateConfigContent(answers, relativeConfigDir);
|
|
1324
1427
|
spinner.start("Creating config file...");
|
|
1325
1428
|
await writeFile(configPath, configContent);
|
|
@@ -1362,7 +1465,7 @@ export default defineConfig({
|
|
|
1362
1465
|
}
|
|
1363
1466
|
|
|
1364
1467
|
// src/commands/watch.ts
|
|
1365
|
-
var
|
|
1468
|
+
var import_node_path6 = __toESM(require("path"));
|
|
1366
1469
|
var import_chalk3 = __toESM(require("chalk"));
|
|
1367
1470
|
var import_chokidar = __toESM(require("chokidar"));
|
|
1368
1471
|
var import_ora3 = __toESM(require("ora"));
|
|
@@ -1384,7 +1487,7 @@ async function watch(options = {}) {
|
|
|
1384
1487
|
spinner.start("Generating icon components...");
|
|
1385
1488
|
const initialStats = await generateIcons(config);
|
|
1386
1489
|
spinner.succeed(`Generated ${import_chalk3.default.green(initialStats.success)} icon components`);
|
|
1387
|
-
const watchPath =
|
|
1490
|
+
const watchPath = import_node_path6.default.join(config.input, "**/*.svg");
|
|
1388
1491
|
const debounce = config.watch?.debounce ?? 300;
|
|
1389
1492
|
const ignore = config.watch?.ignore ?? ["**/node_modules/**", "**/.git/**"];
|
|
1390
1493
|
console.log(import_chalk3.default.bold("\nWatching for changes..."));
|
|
@@ -1402,7 +1505,7 @@ async function watch(options = {}) {
|
|
|
1402
1505
|
}).on("change", (filePath) => {
|
|
1403
1506
|
handleChange("changed", filePath, config, debounce, debounceTimer);
|
|
1404
1507
|
}).on("unlink", (filePath) => {
|
|
1405
|
-
console.log(import_chalk3.default.yellow(`SVG file removed: ${
|
|
1508
|
+
console.log(import_chalk3.default.yellow(`SVG file removed: ${import_node_path6.default.basename(filePath)}`));
|
|
1406
1509
|
handleChange("removed", filePath, config, debounce, debounceTimer);
|
|
1407
1510
|
}).on("error", (error) => {
|
|
1408
1511
|
console.error(import_chalk3.default.red(`Watcher error: ${error.message}`));
|
|
@@ -1421,7 +1524,7 @@ ${import_chalk3.default.yellow("Stopping watch mode...")}`);
|
|
|
1421
1524
|
}
|
|
1422
1525
|
}
|
|
1423
1526
|
function handleChange(event, filePath, config, debounce, timer) {
|
|
1424
|
-
const fileName =
|
|
1527
|
+
const fileName = import_node_path6.default.basename(filePath);
|
|
1425
1528
|
if (timer) {
|
|
1426
1529
|
clearTimeout(timer);
|
|
1427
1530
|
}
|
package/dist/index.mjs
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vectify",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.2",
|
|
4
4
|
"packageManager": "pnpm@9.15.9",
|
|
5
5
|
"description": "A powerful command-line tool to generate React, Vue, and Svelte icon components from SVG files",
|
|
6
6
|
"author": "Xiaobing Zhu <hellozxb252@gmail.com>",
|