@number10/jsx-icon-generator 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +667 -0
- package/README.md +74 -0
- package/dist/generate-icon-loaders.d.ts +1 -0
- package/dist/generate-icon-loaders.js +224 -0
- package/dist/generate-icon-types.d.ts +1 -0
- package/dist/generate-icon-types.js +135 -0
- package/dist/generate-icons.d.ts +36 -0
- package/dist/generate-icons.js +502 -0
- package/dist/icon-generator-config.d.ts +86 -0
- package/dist/icon-generator-config.js +9 -0
- package/dist/vite-plugin-icons.d.ts +28 -0
- package/dist/vite-plugin-icons.js +109 -0
- package/package.json +71 -0
package/README.md
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# @number10/jsx-icon-generator
|
|
2
|
+
|
|
3
|
+
CLI tooling and Vite plugin for generating type-safe icon types and dynamic loaders from icon libraries.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Type generation** — Generate TypeScript union types from SVG icons in packages or directories
|
|
8
|
+
- **Loader generation** — Scan your codebase for icon usage and generate dynamic import loaders
|
|
9
|
+
- **Vite plugin** — Automatic icon generation during development and build
|
|
10
|
+
- **Multi-source** — Combine icons from multiple packages and directories
|
|
11
|
+
- **Watch mode** — Regenerate on file changes during development
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
pnpm add -D @number10/jsx-icon-generator
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## CLI Usage
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
# Generate icon types
|
|
23
|
+
generate-icon-types -p bootstrap-icons -o ./src/icon-types.generated.ts
|
|
24
|
+
|
|
25
|
+
# Generate icon loaders
|
|
26
|
+
generate-icon-loaders -s ./src -o ./src/icon-loaders.generated.ts -p bootstrap-icons
|
|
27
|
+
|
|
28
|
+
# Unified generator with config file
|
|
29
|
+
generate-icons --config ./icon-generator.config.ts
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Vite Plugin
|
|
33
|
+
|
|
34
|
+
```typescript
|
|
35
|
+
import { defineConfig } from 'vite'
|
|
36
|
+
import { iconGeneratorPlugin } from '@number10/jsx-icon-generator/vite-plugin-icons'
|
|
37
|
+
|
|
38
|
+
export default defineConfig({
|
|
39
|
+
plugins: [
|
|
40
|
+
iconGeneratorPlugin({
|
|
41
|
+
configPath: './icon-generator.config.ts',
|
|
42
|
+
}),
|
|
43
|
+
],
|
|
44
|
+
})
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Configuration
|
|
48
|
+
|
|
49
|
+
```typescript
|
|
50
|
+
import { defineIconConfig } from '@number10/jsx-icon-generator/icon-generator-config'
|
|
51
|
+
|
|
52
|
+
export default defineIconConfig({
|
|
53
|
+
source: {
|
|
54
|
+
package: 'bootstrap-icons',
|
|
55
|
+
iconsPath: 'icons',
|
|
56
|
+
},
|
|
57
|
+
types: {
|
|
58
|
+
enabled: true,
|
|
59
|
+
output: './src/icon-types.generated.ts',
|
|
60
|
+
typeName: 'IconType',
|
|
61
|
+
},
|
|
62
|
+
loaders: {
|
|
63
|
+
enabled: true,
|
|
64
|
+
output: './src/icon-loaders.generated.ts',
|
|
65
|
+
scanDir: './src',
|
|
66
|
+
componentNames: ['Icon'],
|
|
67
|
+
validate: true,
|
|
68
|
+
},
|
|
69
|
+
})
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## License
|
|
73
|
+
|
|
74
|
+
GPL-3.0-only
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { readFile, readdir, writeFile } from "node:fs/promises";
|
|
3
|
+
import { join, resolve } from "node:path";
|
|
4
|
+
import { parseArgs } from "node:util";
|
|
5
|
+
//#region src/generate-icon-loaders.ts
|
|
6
|
+
/**
|
|
7
|
+
* Auto-generates icon loader registry from actual icon usage in the codebase
|
|
8
|
+
* Scans TSX/TS files for Icon component usage and generates loaders
|
|
9
|
+
*
|
|
10
|
+
* Usage:
|
|
11
|
+
* generate-icon-loaders --source ./src --output ./src/components/icon-loaders.generated.ts --package bootstrap-icons
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Recursively find all TypeScript files
|
|
15
|
+
*/
|
|
16
|
+
async function findTsFiles(dir) {
|
|
17
|
+
const files = [];
|
|
18
|
+
const entries = await readdir(dir, { withFileTypes: true });
|
|
19
|
+
for (const entry of entries) {
|
|
20
|
+
const fullPath = join(dir, entry.name);
|
|
21
|
+
if (entry.isDirectory()) {
|
|
22
|
+
if (entry.name === "node_modules" || entry.name === "dist") continue;
|
|
23
|
+
files.push(...await findTsFiles(fullPath));
|
|
24
|
+
} else if (entry.isFile() && /\.(tsx?|jsx?)$/.test(entry.name)) files.push(fullPath);
|
|
25
|
+
}
|
|
26
|
+
return files;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Extract icon names from file content
|
|
30
|
+
*/
|
|
31
|
+
function escapeRegExp(value) {
|
|
32
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
33
|
+
}
|
|
34
|
+
function addStringLiteralIcons(expression, iconNames) {
|
|
35
|
+
const stringLiteralPattern = /(["'])([^"'\r\n]+)\1/g;
|
|
36
|
+
let match;
|
|
37
|
+
while ((match = stringLiteralPattern.exec(expression)) !== null) {
|
|
38
|
+
const iconName = match[2];
|
|
39
|
+
if (iconName) iconNames.add(iconName);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
function addIconTypeDeclarationIcons(content, iconNames) {
|
|
43
|
+
const iconTypeLiteralDeclarationPattern = /\b(?:const|let|var)\s+\w+\s*:\s*[^=;\r\n]*\bIconType\b[^=;\r\n]*=\s*(["'])([^"']+)\1/g;
|
|
44
|
+
let match;
|
|
45
|
+
while ((match = iconTypeLiteralDeclarationPattern.exec(content)) !== null) {
|
|
46
|
+
const iconName = match[2];
|
|
47
|
+
if (iconName) iconNames.add(iconName);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function extractIconNames(content, componentNames) {
|
|
51
|
+
const iconNames = /* @__PURE__ */ new Set();
|
|
52
|
+
let match;
|
|
53
|
+
for (const componentName of componentNames) {
|
|
54
|
+
const escapedComponentName = escapeRegExp(componentName);
|
|
55
|
+
const typePattern = new RegExp(`<${escapedComponentName}\\s+[^>]*\\btype=(?:["']([^"']+)["']|\\{['"]([^"']+)["']\\})`, "g");
|
|
56
|
+
while ((match = typePattern.exec(content)) !== null) {
|
|
57
|
+
const iconName = match[1] || match[2];
|
|
58
|
+
if (iconName) iconNames.add(iconName);
|
|
59
|
+
}
|
|
60
|
+
const typeExpressionPattern = new RegExp(`<${escapedComponentName}\\s+[^>]*\\btype=\\{([^}]*)\\}`, "g");
|
|
61
|
+
while ((match = typeExpressionPattern.exec(content)) !== null) {
|
|
62
|
+
const expression = match[1];
|
|
63
|
+
if (expression) addStringLiteralIcons(expression, iconNames);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
addIconTypeDeclarationIcons(content, iconNames);
|
|
67
|
+
const themedPattern = /themed\.(\w*[Ii]con)\s*\?\?\s*["']([^"']+)["']/g;
|
|
68
|
+
while ((match = themedPattern.exec(content)) !== null) if (match[2]) iconNames.add(match[2]);
|
|
69
|
+
const iconPropPattern = /(?:icon|iconType):\s*["']([^"']+)["']/g;
|
|
70
|
+
while ((match = iconPropPattern.exec(content)) !== null) if (match[1]) iconNames.add(match[1]);
|
|
71
|
+
return iconNames;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Load available icon names from generated types file
|
|
75
|
+
*/
|
|
76
|
+
async function loadAvailableIcons(typesFile) {
|
|
77
|
+
try {
|
|
78
|
+
const match = (await readFile(typesFile, "utf-8")).match(/(?:export\s+)?type\s+\w+\s*=\s*([\s\S]+?)(?=\n\nexport|\n\/\/|$)/s);
|
|
79
|
+
if (!match?.[1]) return null;
|
|
80
|
+
const typeContent = match[1];
|
|
81
|
+
const icons = /* @__PURE__ */ new Set();
|
|
82
|
+
const iconPattern = /'([^']+)'/g;
|
|
83
|
+
let iconMatch;
|
|
84
|
+
while ((iconMatch = iconPattern.exec(typeContent)) !== null) {
|
|
85
|
+
const iconName = iconMatch[1];
|
|
86
|
+
if (iconName) icons.add(iconName);
|
|
87
|
+
}
|
|
88
|
+
return icons;
|
|
89
|
+
} catch {
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Main generator function
|
|
95
|
+
*/
|
|
96
|
+
async function generateIconLoaders(options) {
|
|
97
|
+
try {
|
|
98
|
+
const cwd = process.cwd();
|
|
99
|
+
const srcDir = resolve(cwd, options.source);
|
|
100
|
+
const componentNames = options.componentNames || [options.componentName || "Icon"];
|
|
101
|
+
console.log(`📁 Scanning directory: ${srcDir}`);
|
|
102
|
+
console.log(`🔍 Looking for components: ${componentNames.join(", ")}`);
|
|
103
|
+
let availableIcons = null;
|
|
104
|
+
if (options.typesFile) {
|
|
105
|
+
availableIcons = await loadAvailableIcons(resolve(cwd, options.typesFile));
|
|
106
|
+
if (availableIcons) console.log(`✓ Loaded ${availableIcons.size} available icons from ${options.typesFile}`);
|
|
107
|
+
else console.warn(`⚠️ Could not parse types file: ${options.typesFile}`);
|
|
108
|
+
}
|
|
109
|
+
const files = await findTsFiles(srcDir);
|
|
110
|
+
console.log(`📄 Found ${files.length} TypeScript files`);
|
|
111
|
+
const allIconNames = /* @__PURE__ */ new Set();
|
|
112
|
+
for (const file of files) extractIconNames(await readFile(file, "utf-8"), componentNames).forEach((icon) => allIconNames.add(icon));
|
|
113
|
+
let iconArray = Array.from(allIconNames).sort();
|
|
114
|
+
if (availableIcons) {
|
|
115
|
+
const invalidIcons = iconArray.filter((icon) => !availableIcons.has(icon));
|
|
116
|
+
if (invalidIcons.length > 0) {
|
|
117
|
+
console.warn(`⚠️ Found ${invalidIcons.length} icons not in types file:`);
|
|
118
|
+
console.warn(` ${invalidIcons.slice(0, 5).join(", ")}${invalidIcons.length > 5 ? "..." : ""}`);
|
|
119
|
+
}
|
|
120
|
+
iconArray = iconArray.filter((icon) => availableIcons.has(icon));
|
|
121
|
+
}
|
|
122
|
+
console.log(`✓ Found ${iconArray.length} unique icons`);
|
|
123
|
+
if (iconArray.length > 0) console.log(` Icons: ${iconArray.slice(0, 10).join(", ")}${iconArray.length > 10 ? "..." : ""}`);
|
|
124
|
+
const iconsPath = options.iconsPath || "icons";
|
|
125
|
+
const loaders = iconArray.map((icon) => ` '${icon}': () => import('${options.package}/${iconsPath}/${icon}.svg'),`).join("\n");
|
|
126
|
+
const output = `/**
|
|
127
|
+
* Auto-generated icon loader registry
|
|
128
|
+
* Package: ${options.package}
|
|
129
|
+
* Icons found: ${iconArray.length}
|
|
130
|
+
*
|
|
131
|
+
* @generated by @number10/jsx-icon-generator/generate-icon-loaders
|
|
132
|
+
* @cspell: disable
|
|
133
|
+
*/
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Icon loaders - only icons used in the codebase are registered
|
|
137
|
+
* Bundler will create separate chunks for each icon
|
|
138
|
+
*/
|
|
139
|
+
export const iconLoaders: Record<string, () => Promise<{ default: string }>> = {
|
|
140
|
+
${loaders || " // No icons found"}
|
|
141
|
+
}
|
|
142
|
+
`;
|
|
143
|
+
const outputPath = resolve(cwd, options.output);
|
|
144
|
+
await writeFile(outputPath, output, "utf-8");
|
|
145
|
+
console.log(`✓ Generated: ${outputPath}`);
|
|
146
|
+
console.log(`✓ Registered ${iconArray.length} icon loaders`);
|
|
147
|
+
} catch (error) {
|
|
148
|
+
console.error("❌ Error generating icon loaders:", error);
|
|
149
|
+
process.exit(1);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
var { values } = parseArgs({ options: {
|
|
153
|
+
source: {
|
|
154
|
+
type: "string",
|
|
155
|
+
short: "s"
|
|
156
|
+
},
|
|
157
|
+
output: {
|
|
158
|
+
type: "string",
|
|
159
|
+
short: "o"
|
|
160
|
+
},
|
|
161
|
+
package: {
|
|
162
|
+
type: "string",
|
|
163
|
+
short: "p"
|
|
164
|
+
},
|
|
165
|
+
iconsPath: {
|
|
166
|
+
type: "string",
|
|
167
|
+
short: "i"
|
|
168
|
+
},
|
|
169
|
+
componentName: {
|
|
170
|
+
type: "string",
|
|
171
|
+
short: "c"
|
|
172
|
+
},
|
|
173
|
+
componentNames: {
|
|
174
|
+
type: "string",
|
|
175
|
+
multiple: true
|
|
176
|
+
},
|
|
177
|
+
typesFile: {
|
|
178
|
+
type: "string",
|
|
179
|
+
short: "t"
|
|
180
|
+
},
|
|
181
|
+
help: {
|
|
182
|
+
type: "boolean",
|
|
183
|
+
short: "h"
|
|
184
|
+
}
|
|
185
|
+
} });
|
|
186
|
+
if (values.help || !values.source || !values.output || !values.package) {
|
|
187
|
+
console.log(`
|
|
188
|
+
Usage: generate-icon-loaders [options]
|
|
189
|
+
|
|
190
|
+
Options:
|
|
191
|
+
-s, --source <path> Source directory to scan (e.g., ./src)
|
|
192
|
+
-o, --output <path> Output file path (e.g., ./src/components/icon-loaders.generated.ts)
|
|
193
|
+
-p, --package <name> Icon package name (e.g., bootstrap-icons)
|
|
194
|
+
-i, --iconsPath <path> Relative path to icons in package (default: icons)
|
|
195
|
+
-c, --componentName <name> Icon component name to search for (default: Icon)
|
|
196
|
+
--componentNames <names...> Multiple component names (e.g., Icon BootstrapIcon)
|
|
197
|
+
-t, --typesFile <path> Types file for validation (e.g., ./src/icon-types.generated.ts)
|
|
198
|
+
-h, --help Show this help message
|
|
199
|
+
|
|
200
|
+
Examples:
|
|
201
|
+
# Single component name
|
|
202
|
+
generate-icon-loaders -s ./src -o ./src/icon-loaders.generated.ts -p bootstrap-icons
|
|
203
|
+
|
|
204
|
+
# Multiple component names
|
|
205
|
+
generate-icon-loaders -s ./src -o ./src/icon-loaders.generated.ts -p bootstrap-icons \\
|
|
206
|
+
--componentNames Icon BootstrapIcon CustomIcon
|
|
207
|
+
|
|
208
|
+
# With validation
|
|
209
|
+
generate-icon-loaders -s ./src -o ./src/icon-loaders.generated.ts -p bootstrap-icons \\
|
|
210
|
+
-t ./src/icon-types.generated.ts
|
|
211
|
+
`);
|
|
212
|
+
process.exit(values.help ? 0 : 1);
|
|
213
|
+
}
|
|
214
|
+
var options = {
|
|
215
|
+
source: values.source,
|
|
216
|
+
output: values.output,
|
|
217
|
+
package: values.package
|
|
218
|
+
};
|
|
219
|
+
if (values.iconsPath) options.iconsPath = values.iconsPath;
|
|
220
|
+
if (values.componentName) options.componentName = values.componentName;
|
|
221
|
+
if (values.componentNames && values.componentNames.length > 0) options.componentNames = values.componentNames;
|
|
222
|
+
if (values.typesFile) options.typesFile = values.typesFile;
|
|
223
|
+
generateIconLoaders(options);
|
|
224
|
+
//#endregion
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { readdir, writeFile } from "node:fs/promises";
|
|
3
|
+
import { basename, join, resolve } from "node:path";
|
|
4
|
+
import { parseArgs } from "node:util";
|
|
5
|
+
//#region src/generate-icon-types.ts
|
|
6
|
+
/**
|
|
7
|
+
* Generator for icon type definitions from any icon library
|
|
8
|
+
* Scans an icon package and generates TypeScript union type
|
|
9
|
+
*
|
|
10
|
+
* Usage:
|
|
11
|
+
* generate-icon-types --package bootstrap-icons --output ./src/types/icons.ts
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Find icon package in node_modules
|
|
15
|
+
*/
|
|
16
|
+
async function findIconPackage(packageName, cwd) {
|
|
17
|
+
const fs = await import("node:fs");
|
|
18
|
+
const pnpmBase = join(cwd, "node_modules/.pnpm");
|
|
19
|
+
if (fs.existsSync(pnpmBase)) {
|
|
20
|
+
const entries = await readdir(pnpmBase);
|
|
21
|
+
for (const entry of entries) if (entry.startsWith(`${packageName}@`)) {
|
|
22
|
+
const packagePath = join(pnpmBase, entry, "node_modules", packageName);
|
|
23
|
+
if (fs.existsSync(packagePath)) return packagePath;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
const standardPath = join(cwd, "node_modules", packageName);
|
|
27
|
+
if (fs.existsSync(standardPath)) return standardPath;
|
|
28
|
+
throw new Error(`Could not find package: ${packageName}`);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Main generator function
|
|
32
|
+
*/
|
|
33
|
+
async function generateIconTypes(options) {
|
|
34
|
+
try {
|
|
35
|
+
const cwd = process.cwd();
|
|
36
|
+
let iconsDir;
|
|
37
|
+
let sourceName;
|
|
38
|
+
if (options.directory) {
|
|
39
|
+
iconsDir = resolve(cwd, options.directory);
|
|
40
|
+
sourceName = options.directory;
|
|
41
|
+
console.log(`📁 Scanning directory: ${options.directory}`);
|
|
42
|
+
} else if (options.package) {
|
|
43
|
+
iconsDir = join(await findIconPackage(options.package, cwd), options.iconsPath || "icons");
|
|
44
|
+
sourceName = options.package;
|
|
45
|
+
console.log(`📦 Scanning package: ${options.package}`);
|
|
46
|
+
} else throw new Error("Either --package or --directory must be specified");
|
|
47
|
+
console.log(`📁 Icons directory: ${iconsDir}`);
|
|
48
|
+
const iconNames = (await readdir(iconsDir)).filter((file) => file.endsWith(".svg")).map((file) => basename(file, ".svg")).sort();
|
|
49
|
+
console.log(`✓ Found ${iconNames.length} icons`);
|
|
50
|
+
const typeDefinition = iconNames.map((name) => ` | '${name}'`).join("\n");
|
|
51
|
+
const typeName = options.typeName || "IconType";
|
|
52
|
+
const output = `/**
|
|
53
|
+
* Auto-generated icon type definitions
|
|
54
|
+
* Source: ${sourceName}
|
|
55
|
+
* Total icons: ${iconNames.length}
|
|
56
|
+
*
|
|
57
|
+
* @generated by @number10/jsx-icon-generator/generate-icon-types
|
|
58
|
+
* @cspell: disable
|
|
59
|
+
*/
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* All available icon names from ${sourceName}
|
|
63
|
+
* Type-only definition - no runtime imports, zero bundle impact
|
|
64
|
+
*/
|
|
65
|
+
export type ${typeName} =
|
|
66
|
+
${typeDefinition}
|
|
67
|
+
`;
|
|
68
|
+
const outputPath = resolve(cwd, options.output);
|
|
69
|
+
await writeFile(outputPath, output, "utf-8");
|
|
70
|
+
console.log(`✓ Generated: ${outputPath}`);
|
|
71
|
+
console.log(`✓ Type name: ${typeName}`);
|
|
72
|
+
console.log(`✓ Total icons: ${iconNames.length}`);
|
|
73
|
+
if (iconNames.length > 0) {
|
|
74
|
+
console.log(` First: ${iconNames[0]}`);
|
|
75
|
+
console.log(` Last: ${iconNames[iconNames.length - 1]}`);
|
|
76
|
+
}
|
|
77
|
+
} catch (error) {
|
|
78
|
+
console.error("❌ Error generating icon types:", error);
|
|
79
|
+
process.exit(1);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
var { values } = parseArgs({ options: {
|
|
83
|
+
package: {
|
|
84
|
+
type: "string",
|
|
85
|
+
short: "p"
|
|
86
|
+
},
|
|
87
|
+
directory: {
|
|
88
|
+
type: "string",
|
|
89
|
+
short: "d"
|
|
90
|
+
},
|
|
91
|
+
output: {
|
|
92
|
+
type: "string",
|
|
93
|
+
short: "o"
|
|
94
|
+
},
|
|
95
|
+
typeName: {
|
|
96
|
+
type: "string",
|
|
97
|
+
short: "t"
|
|
98
|
+
},
|
|
99
|
+
iconsPath: {
|
|
100
|
+
type: "string",
|
|
101
|
+
short: "i"
|
|
102
|
+
},
|
|
103
|
+
help: {
|
|
104
|
+
type: "boolean",
|
|
105
|
+
short: "h"
|
|
106
|
+
}
|
|
107
|
+
} });
|
|
108
|
+
if (values.help || !values.package && !values.directory || !values.output) {
|
|
109
|
+
console.log(`
|
|
110
|
+
Usage: generate-icon-types [options]
|
|
111
|
+
|
|
112
|
+
Options:
|
|
113
|
+
-p, --package <name> Icon package name (e.g., bootstrap-icons)
|
|
114
|
+
-d, --directory <path> Local directory with SVG files (alternative to --package)
|
|
115
|
+
-o, --output <path> Output file path (e.g., ./src/types/icons.ts)
|
|
116
|
+
-t, --typeName <name> TypeScript type name (default: IconType)
|
|
117
|
+
-i, --iconsPath <path> Relative path to icons in package (default: icons)
|
|
118
|
+
-h, --help Show this help message
|
|
119
|
+
|
|
120
|
+
Examples:
|
|
121
|
+
# From npm package
|
|
122
|
+
generate-icon-types -p bootstrap-icons -o ./src/icon-types.generated.ts
|
|
123
|
+
|
|
124
|
+
# From local directory
|
|
125
|
+
generate-icon-types -d ./public/icons -o ./src/icon-types.generated.ts
|
|
126
|
+
`);
|
|
127
|
+
process.exit(values.help ? 0 : 1);
|
|
128
|
+
}
|
|
129
|
+
var options = { output: values.output };
|
|
130
|
+
if (values.package) options.package = values.package;
|
|
131
|
+
if (values.directory) options.directory = values.directory;
|
|
132
|
+
if (values.typeName) options.typeName = values.typeName;
|
|
133
|
+
if (values.iconsPath) options.iconsPath = values.iconsPath;
|
|
134
|
+
generateIconTypes(options);
|
|
135
|
+
//#endregion
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { IconGeneratorConfig } from './icon-generator-config';
|
|
2
|
+
/**
|
|
3
|
+
* Generate icon types
|
|
4
|
+
* Exported for use by Vite plugin
|
|
5
|
+
*/
|
|
6
|
+
export declare function generateTypes(config: IconGeneratorConfig, cwd: string): Promise<{
|
|
7
|
+
iconNames: string[];
|
|
8
|
+
sourceIconSets: Map<number, Set<string>>;
|
|
9
|
+
} | null>;
|
|
10
|
+
/**
|
|
11
|
+
* Scan icon sources without generating the types file
|
|
12
|
+
* Used by Vite plugin to get sourceIconSets for loader generation without full type regeneration
|
|
13
|
+
* @param config - Icon generator configuration
|
|
14
|
+
* @param cwd - Current working directory
|
|
15
|
+
* @returns Icon names and source mapping
|
|
16
|
+
*/
|
|
17
|
+
export declare function scanIconSources(config: IconGeneratorConfig, cwd: string): Promise<{
|
|
18
|
+
iconNames: string[];
|
|
19
|
+
sourceIconSets: Map<number, Set<string>>;
|
|
20
|
+
}>;
|
|
21
|
+
/**
|
|
22
|
+
* Generate icon loaders
|
|
23
|
+
* Exported for use by Vite plugin
|
|
24
|
+
*/
|
|
25
|
+
export declare function generateLoaders(config: IconGeneratorConfig, cwd: string, typesResult?: {
|
|
26
|
+
iconNames: string[];
|
|
27
|
+
sourceIconSets: Map<number, Set<string>>;
|
|
28
|
+
}): Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* Load config file
|
|
31
|
+
*/
|
|
32
|
+
/**
|
|
33
|
+
* Load icon generator config file
|
|
34
|
+
* Exported for use by Vite plugin and other tools
|
|
35
|
+
*/
|
|
36
|
+
export declare function loadConfig(configPath: string, cwd?: string): Promise<IconGeneratorConfig>;
|