@number10/phaserjsx 0.6.1 → 4.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.
Files changed (108) hide show
  1. package/README.md +43 -3
  2. package/dist/chunk-C2EiDwsr.cjs +35 -0
  3. package/dist/clip/index.cjs +696 -0
  4. package/dist/clip/index.cjs.map +1 -0
  5. package/dist/clip/index.d.ts +3 -0
  6. package/dist/clip/index.d.ts.map +1 -0
  7. package/dist/clip/index.js +688 -0
  8. package/dist/clip/index.js.map +1 -0
  9. package/dist/clip/stencil-clip-extension.d.ts +18 -0
  10. package/dist/clip/stencil-clip-extension.d.ts.map +1 -0
  11. package/dist/clip/stencil-clip.d.ts +134 -0
  12. package/dist/clip/stencil-clip.d.ts.map +1 -0
  13. package/dist/components/appliers/applyBackground.d.ts +2 -1
  14. package/dist/components/appliers/applyBackground.d.ts.map +1 -1
  15. package/dist/components/appliers/applyGestures.d.ts.map +1 -1
  16. package/dist/components/appliers/applyTooltip.d.ts.map +1 -1
  17. package/dist/components/backgroundImage.d.ts +12 -0
  18. package/dist/components/backgroundImage.d.ts.map +1 -0
  19. package/dist/components/creators/createBackground.d.ts +2 -1
  20. package/dist/components/creators/createBackground.d.ts.map +1 -1
  21. package/dist/components/creators/createGestures.d.ts.map +1 -1
  22. package/dist/components/custom/Accordion.d.ts.map +1 -1
  23. package/dist/components/custom/CharText/CharText.d.ts.map +1 -1
  24. package/dist/components/custom/Dialog.d.ts +1 -1
  25. package/dist/components/custom/Divider.d.ts +1 -1
  26. package/dist/components/custom/Dropdown.d.ts.map +1 -1
  27. package/dist/components/custom/Graphics.d.ts +1 -1
  28. package/dist/components/custom/Graphics.d.ts.map +1 -1
  29. package/dist/components/custom/Icon.d.ts.map +1 -1
  30. package/dist/components/custom/Image.d.ts.map +1 -1
  31. package/dist/components/custom/Joystick.d.ts +1 -1
  32. package/dist/components/custom/NineSlice.d.ts.map +1 -1
  33. package/dist/components/custom/Particles.d.ts +1 -1
  34. package/dist/components/custom/Particles.d.ts.map +1 -1
  35. package/dist/components/custom/Portal.d.ts.map +1 -1
  36. package/dist/components/custom/RefOriginView.d.ts +1 -1
  37. package/dist/components/custom/ScrollView.d.ts.map +1 -1
  38. package/dist/components/custom/Sprite.d.ts +1 -1
  39. package/dist/components/custom/Sprite.d.ts.map +1 -1
  40. package/dist/components/custom/Text.d.ts.map +1 -1
  41. package/dist/components/custom/TileSprite.d.ts +1 -1
  42. package/dist/components/custom/TileSprite.d.ts.map +1 -1
  43. package/dist/components/custom/View.d.ts.map +1 -1
  44. package/dist/components/custom/index.cjs +34 -36
  45. package/dist/components/custom/index.js +2 -37
  46. package/dist/components/primitives/graphics.d.ts.map +1 -1
  47. package/dist/components/primitives/image.d.ts.map +1 -1
  48. package/dist/components/primitives/nineslice.d.ts.map +1 -1
  49. package/dist/components/primitives/particles.d.ts.map +1 -1
  50. package/dist/components/primitives/sprite.d.ts.map +1 -1
  51. package/dist/components/primitives/text.d.ts.map +1 -1
  52. package/dist/components/primitives/tilesprite.d.ts.map +1 -1
  53. package/dist/components/primitives/view.d.ts.map +1 -1
  54. package/dist/custom-C_w8D39m.js +29259 -0
  55. package/dist/custom-C_w8D39m.js.map +1 -0
  56. package/dist/custom-Dp3yAJdU.cjs +30498 -0
  57. package/dist/custom-Dp3yAJdU.cjs.map +1 -0
  58. package/dist/fx/fx-creators/blur.d.ts.map +1 -1
  59. package/dist/fx/fx-creators/color-matrix.d.ts.map +1 -1
  60. package/dist/fx/fx-creators/glow.d.ts.map +1 -1
  61. package/dist/fx/fx-creators/pixelate.d.ts.map +1 -1
  62. package/dist/fx/fx-creators/shadow.d.ts.map +1 -1
  63. package/dist/fx/fx-creators/vignette.d.ts.map +1 -1
  64. package/dist/fx/use-fx.d.ts +3 -3
  65. package/dist/fx/use-fx.d.ts.map +1 -1
  66. package/dist/gestures/gesture-manager.d.ts +3 -1
  67. package/dist/gestures/gesture-manager.d.ts.map +1 -1
  68. package/dist/gestures/gesture-types.d.ts +1 -1
  69. package/dist/gestures/gesture-types.d.ts.map +1 -1
  70. package/dist/hooks.d.ts +9 -8
  71. package/dist/hooks.d.ts.map +1 -1
  72. package/dist/index.cjs +1628 -2837
  73. package/dist/index.cjs.map +1 -1
  74. package/dist/index.d.ts +1 -0
  75. package/dist/index.d.ts.map +1 -1
  76. package/dist/index.js +1430 -2866
  77. package/dist/index.js.map +1 -1
  78. package/dist/jsx-dev-runtime.cjs +12 -7
  79. package/dist/jsx-dev-runtime.cjs.map +1 -1
  80. package/dist/jsx-dev-runtime.js +11 -11
  81. package/dist/jsx-dev-runtime.js.map +1 -1
  82. package/dist/jsx-runtime.cjs +55 -33
  83. package/dist/jsx-runtime.cjs.map +1 -1
  84. package/dist/jsx-runtime.js +56 -37
  85. package/dist/jsx-runtime.js.map +1 -1
  86. package/dist/layout/appliers/background-applier.d.ts.map +1 -1
  87. package/dist/layout/layout-engine.d.ts.map +1 -1
  88. package/dist/layout/types.d.ts +2 -1
  89. package/dist/layout/types.d.ts.map +1 -1
  90. package/dist/scene-backgrounds.d.ts +51 -1
  91. package/dist/scene-backgrounds.d.ts.map +1 -1
  92. package/dist/scripts/generate-icon-loaders.js +146 -143
  93. package/dist/scripts/generate-icon-types.js +94 -83
  94. package/dist/scripts/generate-icons.d.ts +1 -2
  95. package/dist/scripts/generate-icons.d.ts.map +1 -1
  96. package/dist/scripts/generate-icons.js +381 -399
  97. package/dist/scripts/icon-generator-config.d.ts +0 -1
  98. package/dist/scripts/icon-generator-config.js +7 -4
  99. package/dist/theme-base.d.ts.map +1 -1
  100. package/dist/vite-plugin-icons.d.ts +1 -2
  101. package/dist/vite-plugin-icons.js +109 -90
  102. package/package.json +29 -22
  103. package/dist/TransformOriginView-Dw_HKnFH.cjs +0 -17116
  104. package/dist/TransformOriginView-Dw_HKnFH.cjs.map +0 -1
  105. package/dist/TransformOriginView-i8uVBHb1.js +0 -17100
  106. package/dist/TransformOriginView-i8uVBHb1.js.map +0 -1
  107. package/dist/components/custom/index.cjs.map +0 -1
  108. package/dist/components/custom/index.js.map +0 -1
@@ -1,144 +1,146 @@
1
1
  #!/usr/bin/env node
2
2
  import { watch } from "node:fs";
3
- import { readdir, writeFile, readFile, access } from "node:fs/promises";
4
- import { resolve, extname, join, basename, dirname, relative } from "node:path";
3
+ import { access, readFile, readdir, writeFile } from "node:fs/promises";
4
+ import { basename, dirname, extname, join, relative, resolve } from "node:path";
5
5
  import { pathToFileURL } from "node:url";
6
6
  import { parseArgs } from "node:util";
7
- const TS_CONFIG_EXTENSIONS = /* @__PURE__ */ new Set([".ts", ".mts", ".cts", ".tsx"]);
7
+ //#region src/scripts/generate-icons.ts
8
+ /**
9
+ * Unified icon generator
10
+ * Can generate types and/or loaders based on configuration
11
+ *
12
+ * Usage:
13
+ * generate-icons --config ./icon-generator.config.ts
14
+ * generate-icons --types-only
15
+ * generate-icons --loaders-only
16
+ * generate-icons --config ./icon-generator.config.ts --watch
17
+ */
18
+ var TS_CONFIG_EXTENSIONS = new Set([
19
+ ".ts",
20
+ ".mts",
21
+ ".cts",
22
+ ".tsx"
23
+ ]);
24
+ /**
25
+ * Find icon package in node_modules
26
+ */
8
27
  async function findIconPackage(packageName, cwd) {
9
- const fs = await import("node:fs");
10
- const pnpmBase = join(cwd, "node_modules/.pnpm");
11
- if (fs.existsSync(pnpmBase)) {
12
- const entries = await readdir(pnpmBase);
13
- for (const entry of entries) {
14
- if (entry.startsWith(`${packageName}@`)) {
15
- const packagePath = join(pnpmBase, entry, "node_modules", packageName);
16
- if (fs.existsSync(packagePath)) {
17
- return packagePath;
18
- }
19
- }
20
- }
21
- }
22
- const standardPath = join(cwd, "node_modules", packageName);
23
- if (fs.existsSync(standardPath)) {
24
- return standardPath;
25
- }
26
- throw new Error(`Could not find package: ${packageName}`);
28
+ const fs = await import("node:fs");
29
+ const pnpmBase = join(cwd, "node_modules/.pnpm");
30
+ if (fs.existsSync(pnpmBase)) {
31
+ const entries = await readdir(pnpmBase);
32
+ for (const entry of entries) if (entry.startsWith(`${packageName}@`)) {
33
+ const packagePath = join(pnpmBase, entry, "node_modules", packageName);
34
+ if (fs.existsSync(packagePath)) return packagePath;
35
+ }
36
+ }
37
+ const standardPath = join(cwd, "node_modules", packageName);
38
+ if (fs.existsSync(standardPath)) return standardPath;
39
+ throw new Error(`Could not find package: ${packageName}`);
27
40
  }
41
+ /**
42
+ * Recursively find all TypeScript files
43
+ */
28
44
  async function findTsFiles(dir, exclude = []) {
29
- const files = [];
30
- const entries = await readdir(dir, { withFileTypes: true });
31
- for (const entry of entries) {
32
- const fullPath = join(dir, entry.name);
33
- if (exclude.some((pattern) => fullPath.includes(pattern))) continue;
34
- if (entry.isDirectory()) {
35
- if (entry.name === "node_modules" || entry.name === "dist") continue;
36
- files.push(...await findTsFiles(fullPath, exclude));
37
- } else if (entry.isFile() && /\.(tsx?|jsx?)$/.test(entry.name)) {
38
- files.push(fullPath);
39
- }
40
- }
41
- return files;
45
+ const files = [];
46
+ const entries = await readdir(dir, { withFileTypes: true });
47
+ for (const entry of entries) {
48
+ const fullPath = join(dir, entry.name);
49
+ if (exclude.some((pattern) => fullPath.includes(pattern))) continue;
50
+ if (entry.isDirectory()) {
51
+ if (entry.name === "node_modules" || entry.name === "dist") continue;
52
+ files.push(...await findTsFiles(fullPath, exclude));
53
+ } else if (entry.isFile() && /\.(tsx?|jsx?)$/.test(entry.name)) files.push(fullPath);
54
+ }
55
+ return files;
42
56
  }
57
+ /**
58
+ * Extract icon names from file content
59
+ */
43
60
  function extractIconNames(content, componentNames, customPatterns) {
44
- const iconNames = /* @__PURE__ */ new Set();
45
- let match;
46
- for (const componentName of componentNames) {
47
- const typePattern = new RegExp(
48
- `<${componentName}\\s+[^>]*type=(?:["']([^"']+)["']|\\{["']([^"']+)["']\\})`,
49
- "g"
50
- );
51
- while ((match = typePattern.exec(content)) !== null) {
52
- const iconName = match[1] || match[2];
53
- if (iconName) {
54
- iconNames.add(iconName);
55
- }
56
- }
57
- }
58
- const themedPattern = /themed\.(\w*[Ii]con)\s*\?\?\s*["']([^"']+)["']/g;
59
- while ((match = themedPattern.exec(content)) !== null) {
60
- if (match[2]) {
61
- iconNames.add(match[2]);
62
- }
63
- }
64
- const iconPropPattern = /(?:icon|iconType):\s*["']([^"']+)["']/g;
65
- while ((match = iconPropPattern.exec(content)) !== null) {
66
- if (match[1]) {
67
- iconNames.add(match[1]);
68
- }
69
- }
70
- if (customPatterns) {
71
- for (const customPattern of customPatterns) {
72
- const pattern = new RegExp(customPattern.pattern, "g");
73
- while ((match = pattern.exec(content)) !== null) {
74
- const iconName = match[customPattern.captureGroup];
75
- if (iconName) {
76
- iconNames.add(iconName);
77
- }
78
- }
79
- }
80
- }
81
- return iconNames;
61
+ const iconNames = /* @__PURE__ */ new Set();
62
+ let match;
63
+ for (const componentName of componentNames) {
64
+ const typePattern = new RegExp(`<${componentName}\\s+[^>]*type=(?:["']([^"']+)["']|\\{["']([^"']+)["']\\})`, "g");
65
+ while ((match = typePattern.exec(content)) !== null) {
66
+ const iconName = match[1] || match[2];
67
+ if (iconName) iconNames.add(iconName);
68
+ }
69
+ }
70
+ const themedPattern = /themed\.(\w*[Ii]con)\s*\?\?\s*["']([^"']+)["']/g;
71
+ while ((match = themedPattern.exec(content)) !== null) if (match[2]) iconNames.add(match[2]);
72
+ const iconPropPattern = /(?:icon|iconType):\s*["']([^"']+)["']/g;
73
+ while ((match = iconPropPattern.exec(content)) !== null) if (match[1]) iconNames.add(match[1]);
74
+ if (customPatterns) for (const customPattern of customPatterns) {
75
+ const pattern = new RegExp(customPattern.pattern, "g");
76
+ while ((match = pattern.exec(content)) !== null) {
77
+ const iconName = match[customPattern.captureGroup];
78
+ if (iconName) iconNames.add(iconName);
79
+ }
80
+ }
81
+ return iconNames;
82
82
  }
83
+ /**
84
+ * Load available icons from types file
85
+ */
83
86
  async function loadAvailableIcons(typesFile) {
84
- try {
85
- const content = await readFile(typesFile, "utf-8");
86
- const match = content.match(/(?:export\s+)?type\s+\w+\s*=\s*([\s\S]+?)(?=\n\nexport|\n\/\/|$)/s);
87
- if (!match?.[1]) return null;
88
- const typeContent = match[1];
89
- const icons = /* @__PURE__ */ new Set();
90
- const iconPattern = /'([^']+)'/g;
91
- let iconMatch;
92
- while ((iconMatch = iconPattern.exec(typeContent)) !== null) {
93
- const iconName = iconMatch[1];
94
- if (iconName) {
95
- icons.add(iconName);
96
- }
97
- }
98
- return icons;
99
- } catch {
100
- return null;
101
- }
87
+ try {
88
+ const match = (await readFile(typesFile, "utf-8")).match(/(?:export\s+)?type\s+\w+\s*=\s*([\s\S]+?)(?=\n\nexport|\n\/\/|$)/s);
89
+ if (!match?.[1]) return null;
90
+ const typeContent = match[1];
91
+ const icons = /* @__PURE__ */ new Set();
92
+ const iconPattern = /'([^']+)'/g;
93
+ let iconMatch;
94
+ while ((iconMatch = iconPattern.exec(typeContent)) !== null) {
95
+ const iconName = iconMatch[1];
96
+ if (iconName) icons.add(iconName);
97
+ }
98
+ return icons;
99
+ } catch {
100
+ return null;
101
+ }
102
102
  }
103
+ /**
104
+ * Generate icon types
105
+ * Exported for use by Vite plugin
106
+ */
103
107
  async function generateTypes(config, cwd) {
104
- if (!config.types?.enabled) return null;
105
- console.log("\nšŸ“ Generating icon types...");
106
- const sources = Array.isArray(config.source) ? config.source : [config.source];
107
- const allIconNames = [];
108
- const sourceInfos = [];
109
- const sourceIconSets = /* @__PURE__ */ new Map();
110
- for (let i = 0; i < sources.length; i++) {
111
- const source = sources[i];
112
- if (!source) continue;
113
- let iconsDir;
114
- let sourceName;
115
- if (source.directory) {
116
- iconsDir = resolve(cwd, source.directory);
117
- sourceName = source.label || source.directory;
118
- console.log(`šŸ“ Scanning directory: ${source.directory}`);
119
- } else if (source.package) {
120
- const packagePath = await findIconPackage(source.package, cwd);
121
- iconsDir = join(packagePath, source.iconsPath || "icons");
122
- sourceName = source.label || source.package;
123
- console.log(`šŸ“¦ Scanning package: ${source.package}`);
124
- } else {
125
- throw new Error("Either source.package or source.directory must be specified");
126
- }
127
- const files = await readdir(iconsDir);
128
- const iconNames = files.filter((file) => file.endsWith(".svg")).map((file) => basename(file, ".svg"));
129
- console.log(`āœ“ Found ${iconNames.length} icons from ${sourceName}`);
130
- allIconNames.push(...iconNames);
131
- sourceInfos.push({ name: sourceName, count: iconNames.length });
132
- sourceIconSets.set(i, new Set(iconNames));
133
- }
134
- const uniqueIconNames = [...new Set(allIconNames)].sort();
135
- console.log(`āœ“ Total unique icons: ${uniqueIconNames.length}`);
136
- const typeDefinition = uniqueIconNames.map((name) => ` | '${name}'`).join("\n");
137
- const typeName = config.types.typeName || "IconType";
138
- const sourceList = sourceInfos.length === 1 && sourceInfos[0] ? sourceInfos[0].name : sourceInfos.map((s) => `${s.name} (${s.count})`).join(", ");
139
- const output = `/**
108
+ if (!config.types?.enabled) return null;
109
+ console.log("\nšŸ“ Generating icon types...");
110
+ const sources = Array.isArray(config.source) ? config.source : [config.source];
111
+ const allIconNames = [];
112
+ const sourceInfos = [];
113
+ const sourceIconSets = /* @__PURE__ */ new Map();
114
+ for (let i = 0; i < sources.length; i++) {
115
+ const source = sources[i];
116
+ if (!source) continue;
117
+ let iconsDir;
118
+ let sourceName;
119
+ if (source.directory) {
120
+ iconsDir = resolve(cwd, source.directory);
121
+ sourceName = source.label || source.directory;
122
+ console.log(`šŸ“ Scanning directory: ${source.directory}`);
123
+ } else if (source.package) {
124
+ iconsDir = join(await findIconPackage(source.package, cwd), source.iconsPath || "icons");
125
+ sourceName = source.label || source.package;
126
+ console.log(`šŸ“¦ Scanning package: ${source.package}`);
127
+ } else throw new Error("Either source.package or source.directory must be specified");
128
+ const iconNames = (await readdir(iconsDir)).filter((file) => file.endsWith(".svg")).map((file) => basename(file, ".svg"));
129
+ console.log(`āœ“ Found ${iconNames.length} icons from ${sourceName}`);
130
+ allIconNames.push(...iconNames);
131
+ sourceInfos.push({
132
+ name: sourceName,
133
+ count: iconNames.length
134
+ });
135
+ sourceIconSets.set(i, new Set(iconNames));
136
+ }
137
+ const uniqueIconNames = [...new Set(allIconNames)].sort();
138
+ console.log(`āœ“ Total unique icons: ${uniqueIconNames.length}`);
139
+ const typeDefinition = uniqueIconNames.map((name) => ` | '${name}'`).join("\n");
140
+ const typeName = config.types.typeName || "IconType";
141
+ const output = `/**
140
142
  * Auto-generated icon type definitions
141
- * Sources: ${sourceList}
143
+ * Sources: ${sourceInfos.length === 1 && sourceInfos[0] ? sourceInfos[0].name : sourceInfos.map((s) => `${s.name} (${s.count})`).join(", ")}
142
144
  * Total unique icons: ${uniqueIconNames.length}
143
145
  *
144
146
  * @generated by @number10/phaserjsx/generate-icons
@@ -152,158 +154,134 @@ async function generateTypes(config, cwd) {
152
154
  export type ${typeName} =
153
155
  ${typeDefinition}
154
156
  `;
155
- const outputPath = resolve(cwd, config.types.output);
156
- await writeFile(outputPath, output, "utf-8");
157
- console.log(`āœ“ Generated: ${outputPath}`);
158
- console.log(`āœ“ Type name: ${typeName}`);
159
- return { iconNames: uniqueIconNames, sourceIconSets };
157
+ const outputPath = resolve(cwd, config.types.output);
158
+ await writeFile(outputPath, output, "utf-8");
159
+ console.log(`āœ“ Generated: ${outputPath}`);
160
+ console.log(`āœ“ Type name: ${typeName}`);
161
+ return {
162
+ iconNames: uniqueIconNames,
163
+ sourceIconSets
164
+ };
160
165
  }
166
+ /**
167
+ * Scan icon sources without generating the types file
168
+ * Used by Vite plugin to get sourceIconSets for loader generation without full type regeneration
169
+ * @param config - Icon generator configuration
170
+ * @param cwd - Current working directory
171
+ * @returns Icon names and source mapping
172
+ */
161
173
  async function scanIconSources(config, cwd) {
162
- const sources = Array.isArray(config.source) ? config.source : [config.source];
163
- const allIconNames = [];
164
- const sourceIconSets = /* @__PURE__ */ new Map();
165
- for (let i = 0; i < sources.length; i++) {
166
- const source = sources[i];
167
- if (!source) continue;
168
- let iconsDir;
169
- if (source.directory) {
170
- iconsDir = resolve(cwd, source.directory);
171
- } else if (source.package) {
172
- const packagePath = await findIconPackage(source.package, cwd);
173
- iconsDir = join(packagePath, source.iconsPath || "icons");
174
- } else {
175
- throw new Error("Either source.package or source.directory must be specified");
176
- }
177
- const files = await readdir(iconsDir);
178
- const iconNames = files.filter((file) => file.endsWith(".svg")).map((file) => basename(file, ".svg"));
179
- allIconNames.push(...iconNames);
180
- sourceIconSets.set(i, new Set(iconNames));
181
- }
182
- const uniqueIconNames = [...new Set(allIconNames)].sort();
183
- return { iconNames: uniqueIconNames, sourceIconSets };
174
+ const sources = Array.isArray(config.source) ? config.source : [config.source];
175
+ const allIconNames = [];
176
+ const sourceIconSets = /* @__PURE__ */ new Map();
177
+ for (let i = 0; i < sources.length; i++) {
178
+ const source = sources[i];
179
+ if (!source) continue;
180
+ let iconsDir;
181
+ if (source.directory) iconsDir = resolve(cwd, source.directory);
182
+ else if (source.package) iconsDir = join(await findIconPackage(source.package, cwd), source.iconsPath || "icons");
183
+ else throw new Error("Either source.package or source.directory must be specified");
184
+ const iconNames = (await readdir(iconsDir)).filter((file) => file.endsWith(".svg")).map((file) => basename(file, ".svg"));
185
+ allIconNames.push(...iconNames);
186
+ sourceIconSets.set(i, new Set(iconNames));
187
+ }
188
+ return {
189
+ iconNames: [...new Set(allIconNames)].sort(),
190
+ sourceIconSets
191
+ };
184
192
  }
193
+ /**
194
+ * Generate icon loaders
195
+ * Exported for use by Vite plugin
196
+ */
185
197
  async function generateLoaders(config, cwd, typesResult) {
186
- if (!config.loaders?.enabled) return;
187
- console.log("\n⚔ Generating icon loaders...");
188
- const scanDir = resolve(cwd, config.loaders.scanDir);
189
- const componentNames = config.loaders.componentNames || ["Icon"];
190
- console.log(`šŸ“ Scanning directory: ${scanDir}`);
191
- console.log(`šŸ” Looking for components: ${componentNames.join(", ")}`);
192
- let availableIconsSet = null;
193
- let sourceIconSets = null;
194
- if (typesResult) {
195
- availableIconsSet = new Set(typesResult.iconNames);
196
- sourceIconSets = typesResult.sourceIconSets;
197
- console.log(`āœ“ Loaded ${availableIconsSet.size} available icons for validation`);
198
- } else if (config.loaders.validate && config.types?.output) {
199
- const typesPath = resolve(cwd, config.types.output);
200
- availableIconsSet = await loadAvailableIcons(typesPath);
201
- if (availableIconsSet) {
202
- console.log(`āœ“ Loaded ${availableIconsSet.size} available icons for validation`);
203
- }
204
- }
205
- const files = await findTsFiles(scanDir, config.exclude);
206
- console.log(`šŸ“„ Found ${files.length} TypeScript files`);
207
- const allIconNames = /* @__PURE__ */ new Set();
208
- for (const file of files) {
209
- const content = await readFile(file, "utf-8");
210
- const icons = extractIconNames(content, componentNames, config.customPatterns);
211
- icons.forEach((icon) => allIconNames.add(icon));
212
- }
213
- let iconArray = Array.from(allIconNames).sort();
214
- if (availableIconsSet) {
215
- const invalidIcons = iconArray.filter((icon) => !availableIconsSet.has(icon));
216
- if (invalidIcons.length > 0) {
217
- console.warn(`āš ļø Found ${invalidIcons.length} icons not in types file:`);
218
- console.warn(
219
- ` ${invalidIcons.slice(0, 5).join(", ")}${invalidIcons.length > 5 ? "..." : ""}`
220
- );
221
- }
222
- iconArray = iconArray.filter((icon) => availableIconsSet.has(icon));
223
- }
224
- console.log(`āœ“ Found ${iconArray.length} unique icons`);
225
- if (iconArray.length > 0) {
226
- console.log(
227
- ` Icons: ${iconArray.slice(0, 10).join(", ")}${iconArray.length > 10 ? "..." : ""}`
228
- );
229
- }
230
- const sources = Array.isArray(config.source) ? config.source : [config.source];
231
- const iconSourceMap = /* @__PURE__ */ new Map();
232
- for (const icon of iconArray) {
233
- if (sourceIconSets) {
234
- for (let i = 0; i < sources.length; i++) {
235
- const source = sources[i];
236
- const iconsForThisSource = sourceIconSets.get(i);
237
- if (!source || !iconsForThisSource) continue;
238
- if (iconsForThisSource.has(icon)) {
239
- let iconPath = "";
240
- if (source.package) {
241
- const packageName = source.package;
242
- const iconsPath = source.iconsPath || "icons";
243
- iconPath = `${packageName}/${iconsPath}/${icon}.svg`;
244
- } else if (source.directory) {
245
- iconPath = `${source.directory}/${icon}.svg`;
246
- }
247
- if (iconPath) {
248
- if (source.directory && config.loaders.output) {
249
- const loaderDir = dirname(resolve(cwd, config.loaders.output));
250
- const iconAbsPath = resolve(cwd, iconPath);
251
- iconPath = relative(loaderDir, iconAbsPath);
252
- iconPath = "./" + iconPath.replace(/\\/g, "/");
253
- }
254
- iconSourceMap.set(icon, {
255
- path: iconPath,
256
- isPackage: !!source.package
257
- });
258
- break;
259
- }
260
- }
261
- }
262
- } else {
263
- for (const source of sources) {
264
- let iconPath = "";
265
- let exists = false;
266
- if (source.package) {
267
- const packageName = source.package;
268
- const iconsPath = source.iconsPath || "icons";
269
- iconPath = `${packageName}/${iconsPath}/${icon}.svg`;
270
- exists = availableIconsSet ? availableIconsSet.has(icon) : true;
271
- } else if (source.directory) {
272
- const dirPath = source.directory;
273
- iconPath = `${dirPath}/${icon}.svg`;
274
- try {
275
- const fullPath = resolve(cwd, dirPath, `${icon}.svg`);
276
- await access(fullPath);
277
- exists = true;
278
- } catch {
279
- exists = false;
280
- }
281
- }
282
- if (exists && iconPath) {
283
- if (source.directory && config.loaders.output) {
284
- const loaderDir = dirname(resolve(cwd, config.loaders.output));
285
- const iconAbsPath = resolve(cwd, iconPath);
286
- iconPath = relative(loaderDir, iconAbsPath);
287
- iconPath = "./" + iconPath.replace(/\\/g, "/");
288
- }
289
- iconSourceMap.set(icon, {
290
- path: iconPath,
291
- isPackage: !!source.package
292
- });
293
- break;
294
- }
295
- }
296
- }
297
- }
298
- const loaderEntries = Array.from(iconSourceMap.entries()).map(([icon, { path, isPackage }]) => {
299
- if (isPackage) {
300
- return ` '${icon}': () => import('${path}?raw'),`;
301
- } else {
302
- return ` '${icon}': () => import('${path}?raw'),`;
303
- }
304
- });
305
- const loaders = loaderEntries.join("\n");
306
- const outputContent = `/**
198
+ if (!config.loaders?.enabled) return;
199
+ console.log("\n⚔ Generating icon loaders...");
200
+ const scanDir = resolve(cwd, config.loaders.scanDir);
201
+ const componentNames = config.loaders.componentNames || ["Icon"];
202
+ console.log(`šŸ“ Scanning directory: ${scanDir}`);
203
+ console.log(`šŸ” Looking for components: ${componentNames.join(", ")}`);
204
+ let availableIconsSet = null;
205
+ let sourceIconSets = null;
206
+ if (typesResult) {
207
+ availableIconsSet = new Set(typesResult.iconNames);
208
+ sourceIconSets = typesResult.sourceIconSets;
209
+ console.log(`āœ“ Loaded ${availableIconsSet.size} available icons for validation`);
210
+ } else if (config.loaders.validate && config.types?.output) {
211
+ availableIconsSet = await loadAvailableIcons(resolve(cwd, config.types.output));
212
+ if (availableIconsSet) console.log(`āœ“ Loaded ${availableIconsSet.size} available icons for validation`);
213
+ }
214
+ const files = await findTsFiles(scanDir, config.exclude);
215
+ console.log(`šŸ“„ Found ${files.length} TypeScript files`);
216
+ const allIconNames = /* @__PURE__ */ new Set();
217
+ for (const file of files) extractIconNames(await readFile(file, "utf-8"), componentNames, config.customPatterns).forEach((icon) => allIconNames.add(icon));
218
+ let iconArray = Array.from(allIconNames).sort();
219
+ if (availableIconsSet) {
220
+ const invalidIcons = iconArray.filter((icon) => !availableIconsSet.has(icon));
221
+ if (invalidIcons.length > 0) {
222
+ console.warn(`āš ļø Found ${invalidIcons.length} icons not in types file:`);
223
+ console.warn(` ${invalidIcons.slice(0, 5).join(", ")}${invalidIcons.length > 5 ? "..." : ""}`);
224
+ }
225
+ iconArray = iconArray.filter((icon) => availableIconsSet.has(icon));
226
+ }
227
+ console.log(`āœ“ Found ${iconArray.length} unique icons`);
228
+ if (iconArray.length > 0) console.log(` Icons: ${iconArray.slice(0, 10).join(", ")}${iconArray.length > 10 ? "..." : ""}`);
229
+ const sources = Array.isArray(config.source) ? config.source : [config.source];
230
+ const iconSourceMap = /* @__PURE__ */ new Map();
231
+ for (const icon of iconArray) if (sourceIconSets) for (let i = 0; i < sources.length; i++) {
232
+ const source = sources[i];
233
+ const iconsForThisSource = sourceIconSets.get(i);
234
+ if (!source || !iconsForThisSource) continue;
235
+ if (iconsForThisSource.has(icon)) {
236
+ let iconPath = "";
237
+ if (source.package) iconPath = `${source.package}/${source.iconsPath || "icons"}/${icon}.svg`;
238
+ else if (source.directory) iconPath = `${source.directory}/${icon}.svg`;
239
+ if (iconPath) {
240
+ if (source.directory && config.loaders.output) {
241
+ iconPath = relative(dirname(resolve(cwd, config.loaders.output)), resolve(cwd, iconPath));
242
+ iconPath = "./" + iconPath.replace(/\\/g, "/");
243
+ }
244
+ iconSourceMap.set(icon, {
245
+ path: iconPath,
246
+ isPackage: !!source.package
247
+ });
248
+ break;
249
+ }
250
+ }
251
+ }
252
+ else for (const source of sources) {
253
+ let iconPath = "";
254
+ let exists = false;
255
+ if (source.package) {
256
+ iconPath = `${source.package}/${source.iconsPath || "icons"}/${icon}.svg`;
257
+ exists = availableIconsSet ? availableIconsSet.has(icon) : true;
258
+ } else if (source.directory) {
259
+ const dirPath = source.directory;
260
+ iconPath = `${dirPath}/${icon}.svg`;
261
+ try {
262
+ await access(resolve(cwd, dirPath, `${icon}.svg`));
263
+ exists = true;
264
+ } catch {
265
+ exists = false;
266
+ }
267
+ }
268
+ if (exists && iconPath) {
269
+ if (source.directory && config.loaders.output) {
270
+ iconPath = relative(dirname(resolve(cwd, config.loaders.output)), resolve(cwd, iconPath));
271
+ iconPath = "./" + iconPath.replace(/\\/g, "/");
272
+ }
273
+ iconSourceMap.set(icon, {
274
+ path: iconPath,
275
+ isPackage: !!source.package
276
+ });
277
+ break;
278
+ }
279
+ }
280
+ const loaders = Array.from(iconSourceMap.entries()).map(([icon, { path, isPackage }]) => {
281
+ if (isPackage) return ` '${icon}': () => import('${path}?raw'),`;
282
+ else return ` '${icon}': () => import('${path}?raw'),`;
283
+ }).join("\n");
284
+ const outputContent = `/**
307
285
  * Auto-generated icon loaders
308
286
  * Generated by scanning: ${config.loaders.scanDir}
309
287
  *
@@ -315,104 +293,109 @@ export const iconLoaders: Record<string, IconLoaderFn> = {
315
293
  ${loaders}
316
294
  }
317
295
  `;
318
- const outputPath = resolve(cwd, config.loaders.output);
319
- await writeFile(outputPath, outputContent, "utf-8");
320
- console.log(`āœ“ Generated: ${outputPath}`);
321
- console.log(`āœ“ Registered ${iconArray.length} icon loaders`);
296
+ const outputPath = resolve(cwd, config.loaders.output);
297
+ await writeFile(outputPath, outputContent, "utf-8");
298
+ console.log(`āœ“ Generated: ${outputPath}`);
299
+ console.log(`āœ“ Registered ${iconArray.length} icon loaders`);
322
300
  }
301
+ /**
302
+ * Load config file
303
+ */
304
+ /**
305
+ * Load icon generator config file
306
+ * Exported for use by Vite plugin and other tools
307
+ */
323
308
  async function loadConfig(configPath, cwd = process.cwd()) {
324
- const absolutePath = resolve(cwd, configPath);
325
- const fileUrl = pathToFileURL(absolutePath).href;
326
- const extension = extname(absolutePath).toLowerCase();
327
- try {
328
- const module = await import(fileUrl);
329
- return module.default || module;
330
- } catch (error) {
331
- const errorMessage = error instanceof Error ? error.message : String(error);
332
- const isUnknownExtension = TS_CONFIG_EXTENSIONS.has(extension) || errorMessage.includes("Unknown file extension");
333
- if (isUnknownExtension) {
334
- try {
335
- const { tsImport } = await import("tsx/esm/api");
336
- const module = await tsImport(fileUrl, import.meta.url);
337
- return module.default || module;
338
- } catch (tsxError) {
339
- const tsxMessage = tsxError instanceof Error ? tsxError.message : String(tsxError);
340
- throw new Error(
341
- `Failed to load config from ${configPath}: ${tsxMessage} (after tsx fallback)`
342
- );
343
- }
344
- }
345
- throw new Error(`Failed to load config from ${configPath}: ${errorMessage}`);
346
- }
309
+ const absolutePath = resolve(cwd, configPath);
310
+ const fileUrl = pathToFileURL(absolutePath).href;
311
+ const extension = extname(absolutePath).toLowerCase();
312
+ try {
313
+ const module = await import(fileUrl);
314
+ return module.default || module;
315
+ } catch (error) {
316
+ const errorMessage = error instanceof Error ? error.message : String(error);
317
+ if (TS_CONFIG_EXTENSIONS.has(extension) || errorMessage.includes("Unknown file extension")) try {
318
+ const { tsImport } = await import("tsx/esm/api");
319
+ const module = await tsImport(fileUrl, import.meta.url);
320
+ return module.default || module;
321
+ } catch (tsxError) {
322
+ const tsxMessage = tsxError instanceof Error ? tsxError.message : String(tsxError);
323
+ throw new Error(`Failed to load config from ${configPath}: ${tsxMessage} (after tsx fallback)`, { cause: tsxError });
324
+ }
325
+ throw new Error(`Failed to load config from ${configPath}: ${errorMessage}`, { cause: error });
326
+ }
347
327
  }
328
+ /**
329
+ * Run generation with config
330
+ */
348
331
  async function runGeneration(config, cwd) {
349
- console.log("šŸŽØ Icon Generator");
350
- console.log("─".repeat(50));
351
- const typesResult = await generateTypes(config, cwd);
352
- await generateLoaders(config, cwd, typesResult || void 0);
353
- console.log("\n✨ Done!\n");
332
+ console.log("šŸŽØ Icon Generator");
333
+ console.log("─".repeat(50));
334
+ await generateLoaders(config, cwd, await generateTypes(config, cwd) || void 0);
335
+ console.log("\n✨ Done!\n");
354
336
  }
337
+ /**
338
+ * Watch mode - monitor files and regenerate on changes
339
+ */
355
340
  async function watchMode(config, cwd) {
356
- console.log("šŸ‘ļø Watch mode enabled");
357
- console.log("šŸ“ Monitoring for changes...\n");
358
- await runGeneration(config, cwd);
359
- const watchDirs = /* @__PURE__ */ new Set();
360
- if (config.loaders?.enabled) {
361
- const scanDir = resolve(cwd, config.loaders.scanDir);
362
- watchDirs.add(scanDir);
363
- }
364
- const sources = Array.isArray(config.source) ? config.source : [config.source];
365
- for (const source of sources) {
366
- if (source.directory) {
367
- watchDirs.add(resolve(cwd, source.directory));
368
- }
369
- }
370
- let regenerateTimeout = null;
371
- const scheduleRegenerate = () => {
372
- if (regenerateTimeout) {
373
- clearTimeout(regenerateTimeout);
374
- }
375
- regenerateTimeout = setTimeout(async () => {
376
- console.log("\nšŸ”„ Changes detected, regenerating...");
377
- try {
378
- await runGeneration(config, cwd);
379
- } catch (error) {
380
- console.error("āŒ Error during regeneration:", error);
381
- }
382
- }, 300);
383
- };
384
- for (const dir of watchDirs) {
385
- const watcher = watch(dir, { recursive: true }, (eventType, filename) => {
386
- if (!filename) return;
387
- if (filename.includes("node_modules") || filename.includes(".git") || filename.endsWith(".generated.ts") || filename.startsWith(".")) {
388
- return;
389
- }
390
- if (/\.(tsx?|svg)$/.test(filename)) {
391
- console.log(`šŸ“ ${eventType}: ${filename}`);
392
- scheduleRegenerate();
393
- }
394
- });
395
- watcher.on("error", (error) => {
396
- console.error(`āŒ Watch error for ${dir}:`, error);
397
- });
398
- }
399
- console.log(`šŸ‘€ Watching ${watchDirs.size} directories`);
400
- console.log("Press Ctrl+C to stop\n");
401
- await new Promise(() => {
402
- });
341
+ console.log("šŸ‘ļø Watch mode enabled");
342
+ console.log("šŸ“ Monitoring for changes...\n");
343
+ await runGeneration(config, cwd);
344
+ const watchDirs = /* @__PURE__ */ new Set();
345
+ if (config.loaders?.enabled) {
346
+ const scanDir = resolve(cwd, config.loaders.scanDir);
347
+ watchDirs.add(scanDir);
348
+ }
349
+ const sources = Array.isArray(config.source) ? config.source : [config.source];
350
+ for (const source of sources) if (source.directory) watchDirs.add(resolve(cwd, source.directory));
351
+ let regenerateTimeout = null;
352
+ const scheduleRegenerate = () => {
353
+ if (regenerateTimeout) clearTimeout(regenerateTimeout);
354
+ regenerateTimeout = setTimeout(async () => {
355
+ console.log("\nšŸ”„ Changes detected, regenerating...");
356
+ try {
357
+ await runGeneration(config, cwd);
358
+ } catch (error) {
359
+ console.error("āŒ Error during regeneration:", error);
360
+ }
361
+ }, 300);
362
+ };
363
+ for (const dir of watchDirs) watch(dir, { recursive: true }, (eventType, filename) => {
364
+ if (!filename) return;
365
+ if (filename.includes("node_modules") || filename.includes(".git") || filename.endsWith(".generated.ts") || filename.startsWith(".")) return;
366
+ if (/\.(tsx?|svg)$/.test(filename)) {
367
+ console.log(`šŸ“ ${eventType}: ${filename}`);
368
+ scheduleRegenerate();
369
+ }
370
+ }).on("error", (error) => {
371
+ console.error(`āŒ Watch error for ${dir}:`, error);
372
+ });
373
+ console.log(`šŸ‘€ Watching ${watchDirs.size} directories`);
374
+ console.log("Press Ctrl+C to stop\n");
375
+ await new Promise(() => {});
403
376
  }
377
+ /**
378
+ * Main function
379
+ */
404
380
  async function main() {
405
- const { values } = parseArgs({
406
- options: {
407
- config: { type: "string", short: "c" },
408
- typesOnly: { type: "boolean" },
409
- loadersOnly: { type: "boolean" },
410
- watch: { type: "boolean", short: "w" },
411
- help: { type: "boolean", short: "h" }
412
- }
413
- });
414
- if (values.help) {
415
- console.log(`
381
+ const { values } = parseArgs({ options: {
382
+ config: {
383
+ type: "string",
384
+ short: "c"
385
+ },
386
+ typesOnly: { type: "boolean" },
387
+ loadersOnly: { type: "boolean" },
388
+ watch: {
389
+ type: "boolean",
390
+ short: "w"
391
+ },
392
+ help: {
393
+ type: "boolean",
394
+ short: "h"
395
+ }
396
+ } });
397
+ if (values.help) {
398
+ console.log(`
416
399
  Usage: generate-icons [options]
417
400
 
418
401
  Options:
@@ -457,38 +440,37 @@ Examples:
457
440
  # Watch mode - regenerate on file changes
458
441
  generate-icons --config ./icon-generator.config.ts --watch
459
442
  `);
460
- process.exit(0);
461
- }
462
- if (!values.config) {
463
- console.error("āŒ Error: --config is required");
464
- console.error("Run with --help for usage information");
465
- process.exit(1);
466
- }
467
- try {
468
- const cwd = process.cwd();
469
- let config = await loadConfig(values.config);
470
- if (values.typesOnly && config.loaders) {
471
- config = { ...config, loaders: { ...config.loaders, enabled: false } };
472
- }
473
- if (values.loadersOnly && config.types) {
474
- config = { ...config, types: { ...config.types, enabled: false } };
475
- }
476
- if (values.watch) {
477
- await watchMode(config, cwd);
478
- } else {
479
- await runGeneration(config, cwd);
480
- }
481
- } catch (error) {
482
- console.error("āŒ Error:", error);
483
- process.exit(1);
484
- }
485
- }
486
- if (import.meta.url === `file://${process.argv[1]}`) {
487
- main();
443
+ process.exit(0);
444
+ }
445
+ if (!values.config) {
446
+ console.error("āŒ Error: --config is required");
447
+ console.error("Run with --help for usage information");
448
+ process.exit(1);
449
+ }
450
+ try {
451
+ const cwd = process.cwd();
452
+ let config = await loadConfig(values.config);
453
+ if (values.typesOnly && config.loaders) config = {
454
+ ...config,
455
+ loaders: {
456
+ ...config.loaders,
457
+ enabled: false
458
+ }
459
+ };
460
+ if (values.loadersOnly && config.types) config = {
461
+ ...config,
462
+ types: {
463
+ ...config.types,
464
+ enabled: false
465
+ }
466
+ };
467
+ if (values.watch) await watchMode(config, cwd);
468
+ else await runGeneration(config, cwd);
469
+ } catch (error) {
470
+ console.error("āŒ Error:", error);
471
+ process.exit(1);
472
+ }
488
473
  }
489
- export {
490
- generateLoaders,
491
- generateTypes,
492
- loadConfig,
493
- scanIconSources
494
- };
474
+ if (import.meta.url === `file://${process.argv[1]}`) main();
475
+ //#endregion
476
+ export { generateLoaders, generateTypes, loadConfig, scanIconSources };