@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.
@@ -0,0 +1,109 @@
1
+ import { resolve } from "node:path";
2
+ //#region src/vite-plugin-icons.ts
3
+ /**
4
+ * Vite plugin for automatic icon generation
5
+ * Integrates icon generator into Vite's build pipeline
6
+ *
7
+ * Usage in vite.config.ts:
8
+ * import { iconGeneratorPlugin } from '@number10/jsx-icon-generator/vite-plugin-icons'
9
+ *
10
+ * export default defineConfig({
11
+ * plugins: [
12
+ * iconGeneratorPlugin({
13
+ * configPath: './icon-generator.config.ts',
14
+ * watch: true, // Enable in dev mode
15
+ * })
16
+ * ]
17
+ * })
18
+ */
19
+ /**
20
+ * Import generation functions dynamically to avoid circular deps
21
+ */
22
+ async function loadGeneratorFunctions() {
23
+ const module = await import("./generate-icons.js");
24
+ return {
25
+ loadConfig: module.loadConfig,
26
+ generateTypes: module.generateTypes,
27
+ generateLoaders: module.generateLoaders,
28
+ scanIconSources: module.scanIconSources
29
+ };
30
+ }
31
+ /**
32
+ * Vite plugin for icon generation
33
+ */
34
+ function iconGeneratorPlugin(options) {
35
+ let config;
36
+ let root;
37
+ let isDevMode = false;
38
+ return {
39
+ name: "vite-plugin-icon-generator",
40
+ async configResolved(resolvedConfig) {
41
+ root = resolvedConfig.root;
42
+ isDevMode = resolvedConfig.command === "serve";
43
+ try {
44
+ const { loadConfig } = await loadGeneratorFunctions();
45
+ config = await loadConfig(options.configPath, root);
46
+ if (options.typesOnly && config.loaders) config = {
47
+ ...config,
48
+ loaders: {
49
+ ...config.loaders,
50
+ enabled: false
51
+ }
52
+ };
53
+ if (options.loadersOnly && config.types) config = {
54
+ ...config,
55
+ types: {
56
+ ...config.types,
57
+ enabled: false
58
+ }
59
+ };
60
+ } catch (error) {
61
+ this.error(`Icon Generator Plugin: ${error}`);
62
+ }
63
+ },
64
+ async buildStart() {
65
+ if (!config) return;
66
+ const scanIconDirectory = config.types?.scanIconDirectory ?? options.scanIconDirectory ?? "watch";
67
+ const generateLoadersMode = config.loaders?.generateLoaders ?? options.generateLoaders ?? "watch";
68
+ const shouldGenerateTypes = scanIconDirectory !== "never" && config.types?.enabled;
69
+ const shouldGenerateLoaders = config.loaders?.enabled && (isDevMode ? generateLoadersMode === "start" : true);
70
+ if (!shouldGenerateTypes && !shouldGenerateLoaders) return;
71
+ console.log("🎨 [Icon Generator] Generating icons...");
72
+ try {
73
+ const { generateTypes, generateLoaders, scanIconSources } = await loadGeneratorFunctions();
74
+ let typesResult = shouldGenerateTypes ? await generateTypes(config, root) : null;
75
+ if (shouldGenerateLoaders) {
76
+ if (!typesResult && config.types?.enabled) typesResult = await scanIconSources(config, root);
77
+ await generateLoaders(config, root, typesResult || void 0);
78
+ }
79
+ console.log("✨ [Icon Generator] Done!");
80
+ } catch (error) {
81
+ this.error(`Icon Generator Plugin: ${error}`);
82
+ }
83
+ },
84
+ async handleHotUpdate({ file, server: _server }) {
85
+ if (!isDevMode || !config || options.watch === false) return;
86
+ const scanIconDirectory = config.types?.scanIconDirectory ?? options.scanIconDirectory ?? "watch";
87
+ const generateLoadersMode = config.loaders?.generateLoaders ?? options.generateLoaders ?? "watch";
88
+ const scanDirAbs = config.loaders?.enabled ? resolve(root, config.loaders.scanDir) : null;
89
+ const shouldRegenerateLoaders = generateLoadersMode === "watch" && config.loaders?.enabled && scanDirAbs && file.startsWith(scanDirAbs) && /\.(tsx?|jsx?)$/.test(file) && !file.endsWith(".generated.ts");
90
+ const sourceAbsPaths = (Array.isArray(config.source) ? config.source : [config.source]).filter((s) => s.directory).map((s) => resolve(root, s.directory));
91
+ const shouldRegenerateTypes = scanIconDirectory === "watch" && config.types?.enabled && file.endsWith(".svg") && sourceAbsPaths.some((path) => file.startsWith(path));
92
+ if (shouldRegenerateLoaders || shouldRegenerateTypes) {
93
+ console.log("🔄 [Icon Generator] File changed, regenerating...");
94
+ try {
95
+ const { generateTypes, generateLoaders, scanIconSources } = await loadGeneratorFunctions();
96
+ let typesResult = null;
97
+ if (shouldRegenerateTypes) typesResult = await generateTypes(config, root);
98
+ else if (shouldRegenerateLoaders && config.types?.enabled) if (scanIconDirectory === "watch") typesResult = await generateTypes(config, root);
99
+ else typesResult = await scanIconSources(config, root);
100
+ if (shouldRegenerateLoaders) await generateLoaders(config, root, typesResult || void 0);
101
+ } catch (error) {
102
+ this.error(`Icon Generator Plugin: ${error}`);
103
+ }
104
+ }
105
+ }
106
+ };
107
+ }
108
+ //#endregion
109
+ export { iconGeneratorPlugin };
package/package.json ADDED
@@ -0,0 +1,71 @@
1
+ {
2
+ "name": "@number10/jsx-icon-generator",
3
+ "version": "5.0.0",
4
+ "type": "module",
5
+ "description": "CLI tooling and Vite plugin for generating type-safe icon types and loaders from icon libraries",
6
+ "author": "Michael Rieck (Michael--) <mr@number10.de>",
7
+ "license": "GPL-3.0-only",
8
+ "bin": {
9
+ "generate-icons": "./dist/generate-icons.js",
10
+ "generate-icon-types": "./dist/generate-icon-types.js",
11
+ "generate-icon-loaders": "./dist/generate-icon-loaders.js"
12
+ },
13
+ "exports": {
14
+ "./icon-generator-config": {
15
+ "types": "./dist/icon-generator-config.d.ts",
16
+ "import": "./dist/icon-generator-config.js"
17
+ },
18
+ "./vite-plugin-icons": {
19
+ "types": "./dist/vite-plugin-icons.d.ts",
20
+ "import": "./dist/vite-plugin-icons.js"
21
+ }
22
+ },
23
+ "files": [
24
+ "dist"
25
+ ],
26
+ "publishConfig": {
27
+ "access": "public"
28
+ },
29
+ "repository": {
30
+ "type": "git",
31
+ "url": "https://github.com/Michael--/phaserjsx",
32
+ "directory": "packages/icon-generator"
33
+ },
34
+ "homepage": "https://phaserjsx.number10.de/",
35
+ "bugs": {
36
+ "url": "https://github.com/Michael--/phaserjsx/issues"
37
+ },
38
+ "dependencies": {
39
+ "tsx": "^4.22.3"
40
+ },
41
+ "devDependencies": {
42
+ "@types/node": "^25.9.0",
43
+ "typescript": "^6.0.3",
44
+ "vite": "^8.0.13"
45
+ },
46
+ "keywords": [
47
+ "icon-generator",
48
+ "icon",
49
+ "icons",
50
+ "svg",
51
+ "svg-icons",
52
+ "typescript",
53
+ "type-generation",
54
+ "code-generation",
55
+ "vite-plugin",
56
+ "vite",
57
+ "cli",
58
+ "tree-shaking",
59
+ "dynamic-import",
60
+ "bootstrap-icons",
61
+ "game-development",
62
+ "game-ui"
63
+ ],
64
+ "scripts": {
65
+ "build": "vite build && pnpm build:types",
66
+ "build:types": "tsc --project tsconfig.types.json",
67
+ "lint": "eslint .",
68
+ "format": "prettier --write .",
69
+ "typecheck": "tsc --noEmit"
70
+ }
71
+ }