@yahoo/uds-icons 2.36.0-beta.1 → 2.36.0-beta.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.
Files changed (38) hide show
  1. package/dist/_virtual/_rolldown/runtime.cjs +30 -0
  2. package/dist/cli/dist/lib/colors.cjs +20 -0
  3. package/dist/cli/dist/lib/colors.js +16 -0
  4. package/dist/cli/dist/lib/colors.js.map +1 -0
  5. package/dist/cli/dist/lib/print.cjs +13 -0
  6. package/dist/cli/dist/lib/print.js +13 -0
  7. package/dist/cli/dist/lib/print.js.map +1 -0
  8. package/dist/cli.cjs +7 -0
  9. package/dist/cli.d.cts +4 -0
  10. package/dist/cli.d.ts +4 -0
  11. package/dist/cli.js +5 -0
  12. package/dist/scripts/colorUtils.cjs +82 -0
  13. package/dist/scripts/colorUtils.js +80 -0
  14. package/dist/scripts/colorUtils.js.map +1 -0
  15. package/dist/scripts/normalizeSvgMarkup.cjs +32 -0
  16. package/dist/scripts/normalizeSvgMarkup.js +32 -0
  17. package/dist/scripts/normalizeSvgMarkup.js.map +1 -0
  18. package/dist/scripts/processIconVariant.cjs +45 -0
  19. package/dist/scripts/processIconVariant.js +46 -0
  20. package/dist/scripts/processIconVariant.js.map +1 -0
  21. package/dist/src/cli/createIconsCommand.cjs +77 -0
  22. package/dist/src/cli/createIconsCommand.d.cts +8 -0
  23. package/dist/src/cli/createIconsCommand.d.cts.map +1 -0
  24. package/dist/src/cli/createIconsCommand.d.ts +8 -0
  25. package/dist/src/cli/createIconsCommand.d.ts.map +1 -0
  26. package/dist/src/cli/createIconsCommand.js +76 -0
  27. package/dist/src/cli/createIconsCommand.js.map +1 -0
  28. package/dist/src/createIconsUtils.cjs +228 -0
  29. package/dist/src/createIconsUtils.d.cts +18 -0
  30. package/dist/src/createIconsUtils.d.cts.map +1 -0
  31. package/dist/src/createIconsUtils.d.ts +18 -0
  32. package/dist/src/createIconsUtils.d.ts.map +1 -0
  33. package/dist/src/createIconsUtils.js +227 -0
  34. package/dist/src/createIconsUtils.js.map +1 -0
  35. package/dist/src/generateBarrelFile.cjs +29 -0
  36. package/dist/src/generateBarrelFile.js +27 -0
  37. package/dist/src/generateBarrelFile.js.map +1 -0
  38. package/package.json +12 -1
@@ -0,0 +1,76 @@
1
+ /*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
2
+ import { createIconsFromDirectory } from "../createIconsUtils.js";
3
+ import { cyan, gray, green, magenta, red } from "../../cli/dist/lib/colors.js";
4
+ import { print } from "../../cli/dist/lib/print.js";
5
+ import path from "node:path";
6
+
7
+ //#region src/cli/createIconsCommand.ts
8
+ const showHelp = () => {
9
+ print("");
10
+ print(`${green("uds create-icons")} - Generate grouped IconDefinition modules from SVG files`);
11
+ print("");
12
+ print(`${magenta("Usage:")}`);
13
+ print(` ${cyan("uds create-icons <PATH_TO_INPUT_DIR>")} [options]`);
14
+ print("");
15
+ print(`${magenta("Arguments:")}`);
16
+ print(` ${cyan("PATH_TO_INPUT_DIR")} Directory containing SVGs named IconName-variant-size.svg`);
17
+ print("");
18
+ print(`${magenta("Options:")}`);
19
+ print(` ${cyan("--outDir <path>")} Output directory (default: dist)`);
20
+ print(` ${cyan("--format <ts|js>")} Output format (default: ts)`);
21
+ print(` ${cyan("--help, -h")} Show this help message`);
22
+ print("");
23
+ print(`${magenta("Example:")}`);
24
+ print(` ${gray("uds create-icons ./packages/icons/assets --outDir ./dist/icons")}`);
25
+ print("");
26
+ };
27
+ function getFormat(value) {
28
+ if (!value || typeof value !== "string") return "ts";
29
+ if (value === "ts" || value === "js") return value;
30
+ return null;
31
+ }
32
+ function getOutDir(optionValue) {
33
+ if (!optionValue || typeof optionValue !== "string") return path.resolve(process.cwd(), "dist");
34
+ return path.resolve(process.cwd(), optionValue);
35
+ }
36
+ const makeCreateIconsCommand = () => ({
37
+ name: "create-icons",
38
+ description: "Create grouped IconDefinition modules from SVG assets directory",
39
+ run: async ({ first, options }) => {
40
+ if (options.help === "true" || options.h === "true") {
41
+ showHelp();
42
+ return;
43
+ }
44
+ if (!first) {
45
+ print(red("Missing input directory argument."));
46
+ showHelp();
47
+ process.exitCode = 1;
48
+ return;
49
+ }
50
+ const format = getFormat(options.format);
51
+ if (!format) {
52
+ print(red(`Invalid --format value: ${String(options.format)}. Expected "ts" or "js".`));
53
+ process.exitCode = 1;
54
+ return;
55
+ }
56
+ const inputDir = path.resolve(process.cwd(), first);
57
+ const outDir = getOutDir(options.outDir);
58
+ try {
59
+ const result = await createIconsFromDirectory({
60
+ inputDir,
61
+ outDir,
62
+ format
63
+ });
64
+ print(green(`Generated ${result.generatedCount} icon definition file(s) in ${outDir}.`));
65
+ print(green(`Generated barrel file: ${result.barrelFilePath}`));
66
+ if (result.skippedFiles.length > 0) print(`Skipped ${result.skippedFiles.length} non-matching SVG file(s): ${result.skippedFiles.join(", ")}`);
67
+ } catch (error) {
68
+ print(red(error.message));
69
+ process.exitCode = 1;
70
+ }
71
+ }
72
+ });
73
+
74
+ //#endregion
75
+ export { makeCreateIconsCommand };
76
+ //# sourceMappingURL=createIconsCommand.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createIconsCommand.js","names":[],"sources":["../../../src/cli/createIconsCommand.ts"],"sourcesContent":["import path from 'node:path';\n\nimport type { Command, Props } from '@yahoo/uds-cli/lib';\nimport { cyan, gray, green, magenta, print, red } from '@yahoo/uds-cli/lib';\n\nimport type { OutputFormat } from './createIcons';\nimport { createIconsFromDirectory } from './createIcons';\n\nconst showHelp = () => {\n print('');\n print(`${green('uds create-icons')} - Generate grouped IconDefinition modules from SVG files`);\n print('');\n print(`${magenta('Usage:')}`);\n print(` ${cyan('uds create-icons <PATH_TO_INPUT_DIR>')} [options]`);\n print('');\n print(`${magenta('Arguments:')}`);\n print(\n ` ${cyan('PATH_TO_INPUT_DIR')} Directory containing SVGs named IconName-variant-size.svg`,\n );\n print('');\n print(`${magenta('Options:')}`);\n print(` ${cyan('--outDir <path>')} Output directory (default: dist)`);\n print(` ${cyan('--format <ts|js>')} Output format (default: ts)`);\n print(` ${cyan('--help, -h')} Show this help message`);\n print('');\n print(`${magenta('Example:')}`);\n print(` ${gray('uds create-icons ./packages/icons/assets --outDir ./dist/icons')}`);\n print('');\n};\n\nfunction getFormat(value: string | boolean | undefined): OutputFormat | null {\n if (!value || typeof value !== 'string') {\n return 'ts';\n }\n\n if (value === 'ts' || value === 'js') {\n return value;\n }\n\n return null;\n}\n\nfunction getOutDir(optionValue: string | boolean | undefined): string {\n if (!optionValue || typeof optionValue !== 'string') {\n return path.resolve(process.cwd(), 'dist');\n }\n\n return path.resolve(process.cwd(), optionValue);\n}\n\nconst makeCreateIconsCommand = (): Command => ({\n name: 'create-icons',\n description: 'Create grouped IconDefinition modules from SVG assets directory',\n run: async ({ first, options }: Props) => {\n if (options.help === 'true' || options.h === 'true') {\n showHelp();\n return;\n }\n\n if (!first) {\n print(red('Missing input directory argument.'));\n showHelp();\n process.exitCode = 1;\n return;\n }\n\n const format = getFormat(options.format);\n if (!format) {\n print(red(`Invalid --format value: ${String(options.format)}. Expected \"ts\" or \"js\".`));\n process.exitCode = 1;\n return;\n }\n\n const inputDir = path.resolve(process.cwd(), first);\n const outDir = getOutDir(options.outDir);\n\n try {\n const result = await createIconsFromDirectory({\n inputDir,\n outDir,\n format,\n });\n\n print(green(`Generated ${result.generatedCount} icon definition file(s) in ${outDir}.`));\n print(green(`Generated barrel file: ${result.barrelFilePath}`));\n if (result.skippedFiles.length > 0) {\n print(\n `Skipped ${result.skippedFiles.length} non-matching SVG file(s): ${result.skippedFiles.join(', ')}`,\n );\n }\n } catch (error) {\n print(red((error as Error).message));\n process.exitCode = 1;\n }\n },\n});\n\nexport { makeCreateIconsCommand };\n"],"mappings":";;;;;;;AAQA,MAAM,iBAAiB;AACrB,OAAM,GAAG;AACT,OAAM,GAAG,MAAM,mBAAmB,CAAC,2DAA2D;AAC9F,OAAM,GAAG;AACT,OAAM,GAAG,QAAQ,SAAS,GAAG;AAC7B,OAAM,KAAK,KAAK,uCAAuC,CAAC,YAAY;AACpE,OAAM,GAAG;AACT,OAAM,GAAG,QAAQ,aAAa,GAAG;AACjC,OACE,KAAK,KAAK,oBAAoB,CAAC,8DAChC;AACD,OAAM,GAAG;AACT,OAAM,GAAG,QAAQ,WAAW,GAAG;AAC/B,OAAM,KAAK,KAAK,kBAAkB,CAAC,uCAAuC;AAC1E,OAAM,KAAK,KAAK,mBAAmB,CAAC,iCAAiC;AACrE,OAAM,KAAK,KAAK,aAAa,CAAC,kCAAkC;AAChE,OAAM,GAAG;AACT,OAAM,GAAG,QAAQ,WAAW,GAAG;AAC/B,OAAM,KAAK,KAAK,iEAAiE,GAAG;AACpF,OAAM,GAAG;;AAGX,SAAS,UAAU,OAA0D;AAC3E,KAAI,CAAC,SAAS,OAAO,UAAU,SAC7B,QAAO;AAGT,KAAI,UAAU,QAAQ,UAAU,KAC9B,QAAO;AAGT,QAAO;;AAGT,SAAS,UAAU,aAAmD;AACpE,KAAI,CAAC,eAAe,OAAO,gBAAgB,SACzC,QAAO,KAAK,QAAQ,QAAQ,KAAK,EAAE,OAAO;AAG5C,QAAO,KAAK,QAAQ,QAAQ,KAAK,EAAE,YAAY;;AAGjD,MAAM,gCAAyC;CAC7C,MAAM;CACN,aAAa;CACb,KAAK,OAAO,EAAE,OAAO,cAAqB;AACxC,MAAI,QAAQ,SAAS,UAAU,QAAQ,MAAM,QAAQ;AACnD,aAAU;AACV;;AAGF,MAAI,CAAC,OAAO;AACV,SAAM,IAAI,oCAAoC,CAAC;AAC/C,aAAU;AACV,WAAQ,WAAW;AACnB;;EAGF,MAAM,SAAS,UAAU,QAAQ,OAAO;AACxC,MAAI,CAAC,QAAQ;AACX,SAAM,IAAI,2BAA2B,OAAO,QAAQ,OAAO,CAAC,0BAA0B,CAAC;AACvF,WAAQ,WAAW;AACnB;;EAGF,MAAM,WAAW,KAAK,QAAQ,QAAQ,KAAK,EAAE,MAAM;EACnD,MAAM,SAAS,UAAU,QAAQ,OAAO;AAExC,MAAI;GACF,MAAM,SAAS,MAAM,yBAAyB;IAC5C;IACA;IACA;IACD,CAAC;AAEF,SAAM,MAAM,aAAa,OAAO,eAAe,8BAA8B,OAAO,GAAG,CAAC;AACxF,SAAM,MAAM,0BAA0B,OAAO,iBAAiB,CAAC;AAC/D,OAAI,OAAO,aAAa,SAAS,EAC/B,OACE,WAAW,OAAO,aAAa,OAAO,6BAA6B,OAAO,aAAa,KAAK,KAAK,GAClG;WAEI,OAAO;AACd,SAAM,IAAK,MAAgB,QAAQ,CAAC;AACpC,WAAQ,WAAW;;;CAGxB"}
@@ -0,0 +1,228 @@
1
+ /*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
2
+ const require_runtime = require('../_virtual/_rolldown/runtime.cjs');
3
+ const require_normalizeSvgMarkup = require('../scripts/normalizeSvgMarkup.cjs');
4
+ const require_processIconVariant = require('../scripts/processIconVariant.cjs');
5
+ const require_generateBarrelFile = require('./generateBarrelFile.cjs');
6
+ let node_fs_promises = require("node:fs/promises");
7
+ let node_path = require("node:path");
8
+ node_path = require_runtime.__toESM(node_path);
9
+
10
+ //#region src/createIconsUtils.ts
11
+ const CODEGEN_BANNER = `/**
12
+ * ------------------- GENERATED | DO NOT MODIFY THIS FILE ---------------------
13
+ * This file is generated by create-icons command.
14
+ * To make changes, update source SVGs and rerun the command.
15
+ */`;
16
+ const ICON_PIXEL_TO_SIZE = {
17
+ 12: "xs",
18
+ 16: "sm",
19
+ 24: "md",
20
+ 32: "lg"
21
+ };
22
+ const PIXEL_SIZES = [
23
+ 12,
24
+ 16,
25
+ 24,
26
+ 32
27
+ ];
28
+ const ASSET_FILENAME_RE = /^(.+)-(outline|fill|multicolor|light|dark)-(12|16|24|32)\.svg$/;
29
+ function parseIconAssetFilename(filename) {
30
+ const match = filename.match(ASSET_FILENAME_RE);
31
+ if (!match) return null;
32
+ const [, name, variant, pixelSizeRaw] = match;
33
+ return {
34
+ name,
35
+ variant,
36
+ pixelSize: Number(pixelSizeRaw)
37
+ };
38
+ }
39
+ async function walkSvgFiles(dirPath) {
40
+ const entries = await (0, node_fs_promises.readdir)(dirPath, { withFileTypes: true });
41
+ return (await Promise.all(entries.map(async (entry) => {
42
+ const absolutePath = node_path.default.join(dirPath, entry.name);
43
+ if (entry.isDirectory()) return walkSvgFiles(absolutePath);
44
+ if (entry.isFile() && entry.name.endsWith(".svg")) return [absolutePath];
45
+ return [];
46
+ }))).flat().sort((a, b) => a.localeCompare(b));
47
+ }
48
+ function extractInnerSvgMarkup(svg) {
49
+ const match = svg.match(/<svg[^>]*>([\s\S]*?)<\/svg>/i);
50
+ if (!match || !match[1]) return "";
51
+ return match[1];
52
+ }
53
+ async function processAssetMarkup(assetPath, iconName, variant, pixelSize, getColorMap) {
54
+ const innerSvg = extractInnerSvgMarkup(require_processIconVariant.processIconVariant({
55
+ svg: await (0, node_fs_promises.readFile)(assetPath, "utf-8"),
56
+ component: {
57
+ id: "",
58
+ name: iconName,
59
+ size: pixelSize,
60
+ variant,
61
+ issues: []
62
+ },
63
+ getColorMap
64
+ }).svg);
65
+ if (!innerSvg) return null;
66
+ return require_normalizeSvgMarkup.normalizeSvgMarkup(innerSvg, iconName);
67
+ }
68
+ async function buildGroupedIconAssets(inputDir) {
69
+ const svgFiles = await walkSvgFiles(inputDir);
70
+ const groupedAssets = {};
71
+ const skippedFiles = [];
72
+ for (const absolutePath of svgFiles) {
73
+ const basename = node_path.default.basename(absolutePath);
74
+ const parsed = parseIconAssetFilename(basename);
75
+ if (!parsed) {
76
+ skippedFiles.push(basename);
77
+ continue;
78
+ }
79
+ const size = ICON_PIXEL_TO_SIZE[parsed.pixelSize];
80
+ if (!groupedAssets[parsed.name]) groupedAssets[parsed.name] = {};
81
+ const variantMap = groupedAssets[parsed.name][parsed.variant] ?? {};
82
+ variantMap[size] = absolutePath;
83
+ groupedAssets[parsed.name][parsed.variant] = variantMap;
84
+ }
85
+ return {
86
+ groupedAssets,
87
+ skippedFiles
88
+ };
89
+ }
90
+ async function buildIconDefinition(name, groupedAssets, getColorMap, metadataOverride) {
91
+ const resolvedAssets = groupedAssets ?? {};
92
+ const svg = {};
93
+ const fillMap = {};
94
+ const outlineMap = {};
95
+ const multicolorMap = {};
96
+ const fillAssets = resolvedAssets.fill ?? {};
97
+ const outlineAssets = resolvedAssets.outline ?? {};
98
+ const multicolorAssets = resolvedAssets.multicolor ?? {};
99
+ const lightAssets = resolvedAssets.light ?? {};
100
+ const darkAssets = resolvedAssets.dark ?? {};
101
+ for (const pixelSize of PIXEL_SIZES) {
102
+ const size = ICON_PIXEL_TO_SIZE[pixelSize];
103
+ const fillPath = fillAssets[size];
104
+ if (fillPath) {
105
+ const markup = await processAssetMarkup(fillPath, name, "fill", pixelSize, getColorMap);
106
+ if (markup) fillMap[size] = markup;
107
+ }
108
+ const outlinePath = outlineAssets[size];
109
+ if (outlinePath) {
110
+ const markup = await processAssetMarkup(outlinePath, name, "outline", pixelSize, getColorMap);
111
+ if (markup) outlineMap[size] = markup;
112
+ }
113
+ const multicolorPath = multicolorAssets[size];
114
+ if (multicolorPath) {
115
+ const markup = await processAssetMarkup(multicolorPath, name, "multicolor", pixelSize, getColorMap);
116
+ if (markup) multicolorMap[size] = markup;
117
+ continue;
118
+ }
119
+ const lightPath = lightAssets[size];
120
+ const darkPath = darkAssets[size];
121
+ if (!lightPath && !darkPath) continue;
122
+ const lightMarkup = lightPath ? await processAssetMarkup(lightPath, name, "light", pixelSize, getColorMap) : null;
123
+ const darkMarkup = darkPath ? await processAssetMarkup(darkPath, name, "dark", pixelSize, getColorMap) : null;
124
+ const merged = `${lightMarkup ? `<g class="uds-light-mode-icon">${lightMarkup}</g>` : ""}${darkMarkup ? `<g class="uds-dark-mode-icon">${darkMarkup}</g>` : ""}`;
125
+ if (merged) multicolorMap[size] = merged;
126
+ }
127
+ if (Object.keys(outlineMap).length > 0) svg.outline = outlineMap;
128
+ if (Object.keys(fillMap).length > 0) svg.fill = fillMap;
129
+ if (Object.keys(multicolorMap).length > 0) svg.multicolor = multicolorMap;
130
+ const variants = [];
131
+ if (svg.outline) variants.push("outline");
132
+ if (svg.fill) variants.push("fill");
133
+ if (svg.multicolor) variants.push("multicolor");
134
+ if (variants.length === 0) return null;
135
+ return {
136
+ __iconDefinition: true,
137
+ metadata: {
138
+ name,
139
+ isSvgIcon: true,
140
+ variants,
141
+ category: "Other",
142
+ tags: [],
143
+ ...metadataOverride
144
+ },
145
+ svg
146
+ };
147
+ }
148
+ function toTypescriptModule(icon, banner = CODEGEN_BANNER) {
149
+ const serializedSvg = JSON.stringify(icon.svg, null, 2).replace(/},\n {2}"/g, "},\n\n \"");
150
+ return `${banner}
151
+
152
+ import type {
153
+ IconDefinition,
154
+ IconMarkupMap,
155
+ IconMetadata,
156
+ IconVariant,
157
+ } from '@yahoo/uds-icons/types';
158
+
159
+ const METADATA: IconMetadata = {
160
+ name: ${JSON.stringify(icon.metadata.name)},
161
+ isSvgIcon: true,
162
+ variants: ${JSON.stringify(icon.metadata.variants)} as IconVariant[],
163
+ category: ${JSON.stringify(icon.metadata.category ?? "Other")},
164
+ tags: ${JSON.stringify(icon.metadata.tags ?? [])},
165
+ };
166
+
167
+ const SVG: IconMarkupMap = ${serializedSvg} as const satisfies IconDefinition['svg'];
168
+
169
+ export const ${icon.metadata.name} = {
170
+ __iconDefinition: true,
171
+ metadata: METADATA,
172
+ svg: SVG,
173
+ } as const satisfies IconDefinition;
174
+ `;
175
+ }
176
+ function toJavascriptModule(icon) {
177
+ return `${CODEGEN_BANNER}
178
+
179
+ const METADATA = ${JSON.stringify(icon.metadata, null, 2)};
180
+
181
+ const SVG = ${JSON.stringify(icon.svg, null, 2)};
182
+
183
+ export const ${icon.metadata.name} = {
184
+ __iconDefinition: true,
185
+ metadata: METADATA,
186
+ svg: SVG,
187
+ };
188
+ `;
189
+ }
190
+ async function createIconsFromDirectory(options) {
191
+ const inputStats = await (0, node_fs_promises.stat)(options.inputDir).catch(() => null);
192
+ if (!inputStats || !inputStats.isDirectory()) throw new Error(`Input path is not a directory: ${options.inputDir}`);
193
+ const { groupedAssets, skippedFiles } = await buildGroupedIconAssets(options.inputDir);
194
+ const groupedNames = Object.keys(groupedAssets).sort((a, b) => a.localeCompare(b));
195
+ if (groupedNames.length === 0) throw new Error("No matching icon SVGs found. Expected files like IconName-fill-16.svg.");
196
+ await (0, node_fs_promises.mkdir)(options.outDir, { recursive: true });
197
+ const colorMapData = await (0, node_fs_promises.readFile)(node_path.default.join(options.inputDir, "color-map.json"), "utf-8").then((raw) => JSON.parse(raw)).catch(() => null);
198
+ const getColorMap = (mode) => {
199
+ if (!colorMapData || !colorMapData[mode]) return /* @__PURE__ */ new Map();
200
+ return new Map(Object.entries(colorMapData[mode]));
201
+ };
202
+ let generatedCount = 0;
203
+ const generatedNames = [];
204
+ for (const name of groupedNames) {
205
+ const icon = await buildIconDefinition(name, groupedAssets[name], getColorMap);
206
+ if (!icon) continue;
207
+ const fileExtension = options.format === "js" ? "js" : "tsx";
208
+ await (0, node_fs_promises.writeFile)(node_path.default.join(options.outDir, `${name}.${fileExtension}`), options.format === "js" ? toJavascriptModule(icon) : toTypescriptModule(icon), "utf-8");
209
+ generatedCount++;
210
+ generatedNames.push(name);
211
+ }
212
+ if (generatedCount === 0) throw new Error("No valid icon groups could be generated from the provided SVG files.");
213
+ const barrelFilePath = await require_generateBarrelFile.writeBarrelFile({
214
+ outDir: options.outDir,
215
+ iconNames: generatedNames,
216
+ banner: CODEGEN_BANNER,
217
+ style: "import-and-export"
218
+ });
219
+ return {
220
+ generatedCount,
221
+ generatedNames,
222
+ skippedFiles,
223
+ barrelFilePath
224
+ };
225
+ }
226
+
227
+ //#endregion
228
+ exports.createIconsFromDirectory = createIconsFromDirectory;
@@ -0,0 +1,18 @@
1
+
2
+ //#region src/createIconsUtils.d.ts
3
+ type OutputFormat = 'ts' | 'js';
4
+ type CreateIconsOptions = {
5
+ inputDir: string;
6
+ outDir: string;
7
+ format: OutputFormat;
8
+ };
9
+ type CreateIconsResult = {
10
+ generatedCount: number;
11
+ generatedNames: string[];
12
+ skippedFiles: string[];
13
+ barrelFilePath: string;
14
+ };
15
+ declare function createIconsFromDirectory(options: CreateIconsOptions): Promise<CreateIconsResult>;
16
+ //#endregion
17
+ export { createIconsFromDirectory };
18
+ //# sourceMappingURL=createIconsUtils.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createIconsUtils.d.cts","names":[],"sources":["../../src/createIconsUtils.ts"],"mappings":";;KAcK,YAAA;AAAA,KAmBA,kBAAA;EACH,QAAA;EACA,MAAA;EACA,MAAA,EAAQ,YAAA;AAAA;AAAA,KAGL,iBAAA;EACH,cAAA;EACA,cAAA;EACA,YAAA;EACA,cAAA;AAAA;AAAA,iBAiRa,wBAAA,CAAyB,OAAA,EAAS,kBAAA,GAAqB,OAAA,CAAQ,iBAAA"}
@@ -0,0 +1,18 @@
1
+
2
+ //#region src/createIconsUtils.d.ts
3
+ type OutputFormat = 'ts' | 'js';
4
+ type CreateIconsOptions = {
5
+ inputDir: string;
6
+ outDir: string;
7
+ format: OutputFormat;
8
+ };
9
+ type CreateIconsResult = {
10
+ generatedCount: number;
11
+ generatedNames: string[];
12
+ skippedFiles: string[];
13
+ barrelFilePath: string;
14
+ };
15
+ declare function createIconsFromDirectory(options: CreateIconsOptions): Promise<CreateIconsResult>;
16
+ //#endregion
17
+ export { createIconsFromDirectory };
18
+ //# sourceMappingURL=createIconsUtils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createIconsUtils.d.ts","names":[],"sources":["../../src/createIconsUtils.ts"],"mappings":";;KAcK,YAAA;AAAA,KAmBA,kBAAA;EACH,QAAA;EACA,MAAA;EACA,MAAA,EAAQ,YAAA;AAAA;AAAA,KAGL,iBAAA;EACH,cAAA;EACA,cAAA;EACA,YAAA;EACA,cAAA;AAAA;AAAA,iBAiRa,wBAAA,CAAyB,OAAA,EAAS,kBAAA,GAAqB,OAAA,CAAQ,iBAAA"}
@@ -0,0 +1,227 @@
1
+ /*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
2
+ import { normalizeSvgMarkup } from "../scripts/normalizeSvgMarkup.js";
3
+ import { processIconVariant } from "../scripts/processIconVariant.js";
4
+ import { writeBarrelFile } from "./generateBarrelFile.js";
5
+ import { mkdir, readFile, readdir, stat, writeFile } from "node:fs/promises";
6
+ import path from "node:path";
7
+
8
+ //#region src/createIconsUtils.ts
9
+ const CODEGEN_BANNER = `/**
10
+ * ------------------- GENERATED | DO NOT MODIFY THIS FILE ---------------------
11
+ * This file is generated by create-icons command.
12
+ * To make changes, update source SVGs and rerun the command.
13
+ */`;
14
+ const ICON_PIXEL_TO_SIZE = {
15
+ 12: "xs",
16
+ 16: "sm",
17
+ 24: "md",
18
+ 32: "lg"
19
+ };
20
+ const PIXEL_SIZES = [
21
+ 12,
22
+ 16,
23
+ 24,
24
+ 32
25
+ ];
26
+ const ASSET_FILENAME_RE = /^(.+)-(outline|fill|multicolor|light|dark)-(12|16|24|32)\.svg$/;
27
+ function parseIconAssetFilename(filename) {
28
+ const match = filename.match(ASSET_FILENAME_RE);
29
+ if (!match) return null;
30
+ const [, name, variant, pixelSizeRaw] = match;
31
+ return {
32
+ name,
33
+ variant,
34
+ pixelSize: Number(pixelSizeRaw)
35
+ };
36
+ }
37
+ async function walkSvgFiles(dirPath) {
38
+ const entries = await readdir(dirPath, { withFileTypes: true });
39
+ return (await Promise.all(entries.map(async (entry) => {
40
+ const absolutePath = path.join(dirPath, entry.name);
41
+ if (entry.isDirectory()) return walkSvgFiles(absolutePath);
42
+ if (entry.isFile() && entry.name.endsWith(".svg")) return [absolutePath];
43
+ return [];
44
+ }))).flat().sort((a, b) => a.localeCompare(b));
45
+ }
46
+ function extractInnerSvgMarkup(svg) {
47
+ const match = svg.match(/<svg[^>]*>([\s\S]*?)<\/svg>/i);
48
+ if (!match || !match[1]) return "";
49
+ return match[1];
50
+ }
51
+ async function processAssetMarkup(assetPath, iconName, variant, pixelSize, getColorMap) {
52
+ const innerSvg = extractInnerSvgMarkup(processIconVariant({
53
+ svg: await readFile(assetPath, "utf-8"),
54
+ component: {
55
+ id: "",
56
+ name: iconName,
57
+ size: pixelSize,
58
+ variant,
59
+ issues: []
60
+ },
61
+ getColorMap
62
+ }).svg);
63
+ if (!innerSvg) return null;
64
+ return normalizeSvgMarkup(innerSvg, iconName);
65
+ }
66
+ async function buildGroupedIconAssets(inputDir) {
67
+ const svgFiles = await walkSvgFiles(inputDir);
68
+ const groupedAssets = {};
69
+ const skippedFiles = [];
70
+ for (const absolutePath of svgFiles) {
71
+ const basename = path.basename(absolutePath);
72
+ const parsed = parseIconAssetFilename(basename);
73
+ if (!parsed) {
74
+ skippedFiles.push(basename);
75
+ continue;
76
+ }
77
+ const size = ICON_PIXEL_TO_SIZE[parsed.pixelSize];
78
+ if (!groupedAssets[parsed.name]) groupedAssets[parsed.name] = {};
79
+ const variantMap = groupedAssets[parsed.name][parsed.variant] ?? {};
80
+ variantMap[size] = absolutePath;
81
+ groupedAssets[parsed.name][parsed.variant] = variantMap;
82
+ }
83
+ return {
84
+ groupedAssets,
85
+ skippedFiles
86
+ };
87
+ }
88
+ async function buildIconDefinition(name, groupedAssets, getColorMap, metadataOverride) {
89
+ const resolvedAssets = groupedAssets ?? {};
90
+ const svg = {};
91
+ const fillMap = {};
92
+ const outlineMap = {};
93
+ const multicolorMap = {};
94
+ const fillAssets = resolvedAssets.fill ?? {};
95
+ const outlineAssets = resolvedAssets.outline ?? {};
96
+ const multicolorAssets = resolvedAssets.multicolor ?? {};
97
+ const lightAssets = resolvedAssets.light ?? {};
98
+ const darkAssets = resolvedAssets.dark ?? {};
99
+ for (const pixelSize of PIXEL_SIZES) {
100
+ const size = ICON_PIXEL_TO_SIZE[pixelSize];
101
+ const fillPath = fillAssets[size];
102
+ if (fillPath) {
103
+ const markup = await processAssetMarkup(fillPath, name, "fill", pixelSize, getColorMap);
104
+ if (markup) fillMap[size] = markup;
105
+ }
106
+ const outlinePath = outlineAssets[size];
107
+ if (outlinePath) {
108
+ const markup = await processAssetMarkup(outlinePath, name, "outline", pixelSize, getColorMap);
109
+ if (markup) outlineMap[size] = markup;
110
+ }
111
+ const multicolorPath = multicolorAssets[size];
112
+ if (multicolorPath) {
113
+ const markup = await processAssetMarkup(multicolorPath, name, "multicolor", pixelSize, getColorMap);
114
+ if (markup) multicolorMap[size] = markup;
115
+ continue;
116
+ }
117
+ const lightPath = lightAssets[size];
118
+ const darkPath = darkAssets[size];
119
+ if (!lightPath && !darkPath) continue;
120
+ const lightMarkup = lightPath ? await processAssetMarkup(lightPath, name, "light", pixelSize, getColorMap) : null;
121
+ const darkMarkup = darkPath ? await processAssetMarkup(darkPath, name, "dark", pixelSize, getColorMap) : null;
122
+ const merged = `${lightMarkup ? `<g class="uds-light-mode-icon">${lightMarkup}</g>` : ""}${darkMarkup ? `<g class="uds-dark-mode-icon">${darkMarkup}</g>` : ""}`;
123
+ if (merged) multicolorMap[size] = merged;
124
+ }
125
+ if (Object.keys(outlineMap).length > 0) svg.outline = outlineMap;
126
+ if (Object.keys(fillMap).length > 0) svg.fill = fillMap;
127
+ if (Object.keys(multicolorMap).length > 0) svg.multicolor = multicolorMap;
128
+ const variants = [];
129
+ if (svg.outline) variants.push("outline");
130
+ if (svg.fill) variants.push("fill");
131
+ if (svg.multicolor) variants.push("multicolor");
132
+ if (variants.length === 0) return null;
133
+ return {
134
+ __iconDefinition: true,
135
+ metadata: {
136
+ name,
137
+ isSvgIcon: true,
138
+ variants,
139
+ category: "Other",
140
+ tags: [],
141
+ ...metadataOverride
142
+ },
143
+ svg
144
+ };
145
+ }
146
+ function toTypescriptModule(icon, banner = CODEGEN_BANNER) {
147
+ const serializedSvg = JSON.stringify(icon.svg, null, 2).replace(/},\n {2}"/g, "},\n\n \"");
148
+ return `${banner}
149
+
150
+ import type {
151
+ IconDefinition,
152
+ IconMarkupMap,
153
+ IconMetadata,
154
+ IconVariant,
155
+ } from '@yahoo/uds-icons/types';
156
+
157
+ const METADATA: IconMetadata = {
158
+ name: ${JSON.stringify(icon.metadata.name)},
159
+ isSvgIcon: true,
160
+ variants: ${JSON.stringify(icon.metadata.variants)} as IconVariant[],
161
+ category: ${JSON.stringify(icon.metadata.category ?? "Other")},
162
+ tags: ${JSON.stringify(icon.metadata.tags ?? [])},
163
+ };
164
+
165
+ const SVG: IconMarkupMap = ${serializedSvg} as const satisfies IconDefinition['svg'];
166
+
167
+ export const ${icon.metadata.name} = {
168
+ __iconDefinition: true,
169
+ metadata: METADATA,
170
+ svg: SVG,
171
+ } as const satisfies IconDefinition;
172
+ `;
173
+ }
174
+ function toJavascriptModule(icon) {
175
+ return `${CODEGEN_BANNER}
176
+
177
+ const METADATA = ${JSON.stringify(icon.metadata, null, 2)};
178
+
179
+ const SVG = ${JSON.stringify(icon.svg, null, 2)};
180
+
181
+ export const ${icon.metadata.name} = {
182
+ __iconDefinition: true,
183
+ metadata: METADATA,
184
+ svg: SVG,
185
+ };
186
+ `;
187
+ }
188
+ async function createIconsFromDirectory(options) {
189
+ const inputStats = await stat(options.inputDir).catch(() => null);
190
+ if (!inputStats || !inputStats.isDirectory()) throw new Error(`Input path is not a directory: ${options.inputDir}`);
191
+ const { groupedAssets, skippedFiles } = await buildGroupedIconAssets(options.inputDir);
192
+ const groupedNames = Object.keys(groupedAssets).sort((a, b) => a.localeCompare(b));
193
+ if (groupedNames.length === 0) throw new Error("No matching icon SVGs found. Expected files like IconName-fill-16.svg.");
194
+ await mkdir(options.outDir, { recursive: true });
195
+ const colorMapData = await readFile(path.join(options.inputDir, "color-map.json"), "utf-8").then((raw) => JSON.parse(raw)).catch(() => null);
196
+ const getColorMap = (mode) => {
197
+ if (!colorMapData || !colorMapData[mode]) return /* @__PURE__ */ new Map();
198
+ return new Map(Object.entries(colorMapData[mode]));
199
+ };
200
+ let generatedCount = 0;
201
+ const generatedNames = [];
202
+ for (const name of groupedNames) {
203
+ const icon = await buildIconDefinition(name, groupedAssets[name], getColorMap);
204
+ if (!icon) continue;
205
+ const fileExtension = options.format === "js" ? "js" : "tsx";
206
+ await writeFile(path.join(options.outDir, `${name}.${fileExtension}`), options.format === "js" ? toJavascriptModule(icon) : toTypescriptModule(icon), "utf-8");
207
+ generatedCount++;
208
+ generatedNames.push(name);
209
+ }
210
+ if (generatedCount === 0) throw new Error("No valid icon groups could be generated from the provided SVG files.");
211
+ const barrelFilePath = await writeBarrelFile({
212
+ outDir: options.outDir,
213
+ iconNames: generatedNames,
214
+ banner: CODEGEN_BANNER,
215
+ style: "import-and-export"
216
+ });
217
+ return {
218
+ generatedCount,
219
+ generatedNames,
220
+ skippedFiles,
221
+ barrelFilePath
222
+ };
223
+ }
224
+
225
+ //#endregion
226
+ export { createIconsFromDirectory };
227
+ //# sourceMappingURL=createIconsUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createIconsUtils.js","names":[],"sources":["../../src/createIconsUtils.ts"],"sourcesContent":["import { mkdir, readdir, readFile, stat, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\n\nimport { normalizeSvgMarkup } from '../scripts/normalizeSvgMarkup';\nimport { processIconVariant } from '../scripts/processIconVariant';\nimport { writeBarrelFile } from './generateBarrelFile';\nimport type { IconDefinition, IconMarkupMap, IconPixelSize, IconSize, IconVariant } from './types';\n\nconst CODEGEN_BANNER = `/**\n * ------------------- GENERATED | DO NOT MODIFY THIS FILE ---------------------\n * This file is generated by create-icons command.\n * To make changes, update source SVGs and rerun the command.\n */`;\n\ntype OutputFormat = 'ts' | 'js';\ntype AssetVariant = IconVariant | 'light' | 'dark';\n\ntype ParsedIconAssetFilename = {\n name: string;\n variant: AssetVariant;\n pixelSize: IconPixelSize;\n};\n\ntype GroupedIconAssets = Record<\n string,\n Partial<Record<AssetVariant, Partial<Record<IconSize, string>>>>\n>;\n\ntype IconMetadataOverride = {\n category?: string;\n tags?: string[];\n};\n\ntype CreateIconsOptions = {\n inputDir: string;\n outDir: string;\n format: OutputFormat;\n};\n\ntype CreateIconsResult = {\n generatedCount: number;\n generatedNames: string[];\n skippedFiles: string[];\n barrelFilePath: string;\n};\n\nconst ICON_PIXEL_TO_SIZE: Record<IconPixelSize, IconSize> = {\n 12: 'xs',\n 16: 'sm',\n 24: 'md',\n 32: 'lg',\n};\n\nconst PIXEL_SIZES: readonly IconPixelSize[] = [12, 16, 24, 32];\n\nconst ASSET_FILENAME_RE = /^(.+)-(outline|fill|multicolor|light|dark)-(12|16|24|32)\\.svg$/;\n\nfunction parseIconAssetFilename(filename: string): ParsedIconAssetFilename | null {\n const match = filename.match(ASSET_FILENAME_RE);\n if (!match) {\n return null;\n }\n\n const [, name, variant, pixelSizeRaw] = match;\n return {\n name,\n variant: variant as AssetVariant,\n pixelSize: Number(pixelSizeRaw) as IconPixelSize,\n };\n}\n\nasync function walkSvgFiles(dirPath: string): Promise<string[]> {\n const entries = await readdir(dirPath, { withFileTypes: true });\n const nested = await Promise.all(\n entries.map(async (entry) => {\n const absolutePath = path.join(dirPath, entry.name);\n if (entry.isDirectory()) {\n return walkSvgFiles(absolutePath);\n }\n if (entry.isFile() && entry.name.endsWith('.svg')) {\n return [absolutePath];\n }\n return [];\n }),\n );\n\n return nested.flat().sort((a, b) => a.localeCompare(b));\n}\n\nfunction extractInnerSvgMarkup(svg: string): string {\n const match = svg.match(/<svg[^>]*>([\\s\\S]*?)<\\/svg>/i);\n if (!match || !match[1]) {\n return '';\n }\n return match[1];\n}\n\nasync function processAssetMarkup(\n assetPath: string,\n iconName: string,\n variant: AssetVariant,\n pixelSize: IconPixelSize,\n getColorMap: (mode: 'light' | 'dark') => Map<string, string>,\n): Promise<string | null> {\n const svg = await readFile(assetPath, 'utf-8');\n const processed = processIconVariant({\n svg,\n component: {\n id: '',\n name: iconName,\n size: pixelSize,\n variant,\n issues: [],\n },\n getColorMap,\n });\n\n const innerSvg = extractInnerSvgMarkup(processed.svg);\n if (!innerSvg) {\n return null;\n }\n\n return normalizeSvgMarkup(innerSvg, iconName);\n}\n\nasync function buildGroupedIconAssets(inputDir: string): Promise<{\n groupedAssets: GroupedIconAssets;\n skippedFiles: string[];\n}> {\n const svgFiles = await walkSvgFiles(inputDir);\n const groupedAssets: GroupedIconAssets = {};\n const skippedFiles: string[] = [];\n\n for (const absolutePath of svgFiles) {\n const basename = path.basename(absolutePath);\n const parsed = parseIconAssetFilename(basename);\n\n if (!parsed) {\n skippedFiles.push(basename);\n continue;\n }\n\n const size = ICON_PIXEL_TO_SIZE[parsed.pixelSize];\n\n if (!groupedAssets[parsed.name]) {\n groupedAssets[parsed.name] = {};\n }\n\n const variantMap = groupedAssets[parsed.name][parsed.variant] ?? {};\n variantMap[size] = absolutePath;\n groupedAssets[parsed.name][parsed.variant] = variantMap;\n }\n\n return { groupedAssets, skippedFiles };\n}\n\nasync function buildIconDefinition(\n name: string,\n groupedAssets: GroupedIconAssets[string] | undefined,\n getColorMap: (mode: 'light' | 'dark') => Map<string, string>,\n metadataOverride?: IconMetadataOverride,\n): Promise<IconDefinition | null> {\n const resolvedAssets = groupedAssets ?? {};\n const svg: IconMarkupMap = {};\n\n const fillMap: Partial<Record<IconSize, string>> = {};\n const outlineMap: Partial<Record<IconSize, string>> = {};\n const multicolorMap: Partial<Record<IconSize, string>> = {};\n\n const fillAssets = resolvedAssets.fill ?? {};\n const outlineAssets = resolvedAssets.outline ?? {};\n const multicolorAssets = resolvedAssets.multicolor ?? {};\n const lightAssets = resolvedAssets.light ?? {};\n const darkAssets = resolvedAssets.dark ?? {};\n\n for (const pixelSize of PIXEL_SIZES) {\n const size = ICON_PIXEL_TO_SIZE[pixelSize];\n\n const fillPath = fillAssets[size];\n if (fillPath) {\n const markup = await processAssetMarkup(fillPath, name, 'fill', pixelSize, getColorMap);\n if (markup) {\n fillMap[size] = markup;\n }\n }\n\n const outlinePath = outlineAssets[size];\n if (outlinePath) {\n const markup = await processAssetMarkup(outlinePath, name, 'outline', pixelSize, getColorMap);\n if (markup) {\n outlineMap[size] = markup;\n }\n }\n\n const multicolorPath = multicolorAssets[size];\n if (multicolorPath) {\n const markup = await processAssetMarkup(\n multicolorPath,\n name,\n 'multicolor',\n pixelSize,\n getColorMap,\n );\n if (markup) {\n multicolorMap[size] = markup;\n }\n continue;\n }\n\n const lightPath = lightAssets[size];\n const darkPath = darkAssets[size];\n\n if (!lightPath && !darkPath) {\n continue;\n }\n\n const lightMarkup = lightPath\n ? await processAssetMarkup(lightPath, name, 'light', pixelSize, getColorMap)\n : null;\n const darkMarkup = darkPath\n ? await processAssetMarkup(darkPath, name, 'dark', pixelSize, getColorMap)\n : null;\n\n const merged = `${\n lightMarkup ? `<g class=\"uds-light-mode-icon\">${lightMarkup}</g>` : ''\n }${darkMarkup ? `<g class=\"uds-dark-mode-icon\">${darkMarkup}</g>` : ''}`;\n\n if (merged) {\n multicolorMap[size] = merged;\n }\n }\n\n if (Object.keys(outlineMap).length > 0) {\n svg.outline = outlineMap;\n }\n if (Object.keys(fillMap).length > 0) {\n svg.fill = fillMap;\n }\n if (Object.keys(multicolorMap).length > 0) {\n svg.multicolor = multicolorMap;\n }\n\n const variants: IconVariant[] = [];\n if (svg.outline) {\n variants.push('outline');\n }\n if (svg.fill) {\n variants.push('fill');\n }\n if (svg.multicolor) {\n variants.push('multicolor');\n }\n\n if (variants.length === 0) {\n return null;\n }\n\n return {\n __iconDefinition: true,\n metadata: {\n name,\n isSvgIcon: true,\n variants,\n category: 'Other',\n tags: [],\n ...metadataOverride,\n },\n svg,\n };\n}\n\nfunction toTypescriptModule(icon: IconDefinition, banner = CODEGEN_BANNER): string {\n const serializedSvg = JSON.stringify(icon.svg, null, 2).replace(/},\\n {2}\"/g, '},\\n\\n \"');\n\n return `${banner}\n\nimport type {\n IconDefinition,\n IconMarkupMap,\n IconMetadata,\n IconVariant,\n} from '@yahoo/uds-icons/types';\n\nconst METADATA: IconMetadata = {\n name: ${JSON.stringify(icon.metadata.name)},\n isSvgIcon: true,\n variants: ${JSON.stringify(icon.metadata.variants)} as IconVariant[],\n category: ${JSON.stringify(icon.metadata.category ?? 'Other')},\n tags: ${JSON.stringify(icon.metadata.tags ?? [])},\n};\n\nconst SVG: IconMarkupMap = ${serializedSvg} as const satisfies IconDefinition['svg'];\n\nexport const ${icon.metadata.name} = {\n __iconDefinition: true,\n metadata: METADATA,\n svg: SVG,\n} as const satisfies IconDefinition;\n`;\n}\n\nfunction toJavascriptModule(icon: IconDefinition): string {\n return `${CODEGEN_BANNER}\n\nconst METADATA = ${JSON.stringify(icon.metadata, null, 2)};\n\nconst SVG = ${JSON.stringify(icon.svg, null, 2)};\n\nexport const ${icon.metadata.name} = {\n __iconDefinition: true,\n metadata: METADATA,\n svg: SVG,\n};\n`;\n}\n\nasync function createIconsFromDirectory(options: CreateIconsOptions): Promise<CreateIconsResult> {\n const inputStats = await stat(options.inputDir).catch(() => null);\n if (!inputStats || !inputStats.isDirectory()) {\n throw new Error(`Input path is not a directory: ${options.inputDir}`);\n }\n\n const { groupedAssets, skippedFiles } = await buildGroupedIconAssets(options.inputDir);\n const groupedNames = Object.keys(groupedAssets).sort((a, b) => a.localeCompare(b));\n\n if (groupedNames.length === 0) {\n throw new Error('No matching icon SVGs found. Expected files like IconName-fill-16.svg.');\n }\n\n await mkdir(options.outDir, { recursive: true });\n\n const colorMapPath = path.join(options.inputDir, 'color-map.json');\n const colorMapData = await readFile(colorMapPath, 'utf-8')\n .then((raw) => JSON.parse(raw) as Record<'light' | 'dark', Record<string, string>>)\n .catch(() => null);\n\n const getColorMap = (mode: 'light' | 'dark'): Map<string, string> => {\n if (!colorMapData || !colorMapData[mode]) {\n return new Map<string, string>();\n }\n return new Map<string, string>(Object.entries(colorMapData[mode]));\n };\n\n let generatedCount = 0;\n const generatedNames: string[] = [];\n\n for (const name of groupedNames) {\n const icon = await buildIconDefinition(name, groupedAssets[name], getColorMap);\n if (!icon) {\n continue;\n }\n\n const fileExtension = options.format === 'js' ? 'js' : 'tsx';\n const outputPath = path.join(options.outDir, `${name}.${fileExtension}`);\n const moduleContent =\n options.format === 'js' ? toJavascriptModule(icon) : toTypescriptModule(icon);\n await writeFile(outputPath, moduleContent, 'utf-8');\n generatedCount++;\n generatedNames.push(name);\n }\n\n if (generatedCount === 0) {\n throw new Error('No valid icon groups could be generated from the provided SVG files.');\n }\n\n const barrelFilePath = await writeBarrelFile({\n outDir: options.outDir,\n iconNames: generatedNames,\n banner: CODEGEN_BANNER,\n style: 'import-and-export',\n });\n\n return {\n generatedCount,\n generatedNames,\n skippedFiles,\n barrelFilePath,\n };\n}\n\nexport {\n buildGroupedIconAssets,\n buildIconDefinition,\n createIconsFromDirectory,\n type CreateIconsOptions,\n type CreateIconsResult,\n type GroupedIconAssets,\n type IconMetadataOverride,\n type OutputFormat,\n parseIconAssetFilename,\n toTypescriptModule,\n};\n"],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ /*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
2
+ const require_runtime = require('../_virtual/_rolldown/runtime.cjs');
3
+ let node_fs_promises = require("node:fs/promises");
4
+ node_fs_promises = require_runtime.__toESM(node_fs_promises);
5
+ let node_path = require("node:path");
6
+ node_path = require_runtime.__toESM(node_path);
7
+
8
+ //#region src/generateBarrelFile.ts
9
+ function buildBarrelContent(iconNames, banner, style) {
10
+ const sortedNames = [...iconNames].sort((a, b) => a.localeCompare(b));
11
+ if (style === "export-from") return `${banner}
12
+ ${sortedNames.map((name) => `export { ${name} } from './${name}.js';`).join("\n")}
13
+ `;
14
+ return `${banner}
15
+ ${sortedNames.map((name) => `import { ${name} } from './${name}.js';`).join("\n")}
16
+
17
+ ${sortedNames.map((name) => `export { ${name} };`).join("\n")}
18
+ `;
19
+ }
20
+ async function writeBarrelFile({ outDir, iconNames, banner, style = "import-and-export" }) {
21
+ await node_fs_promises.default.mkdir(outDir, { recursive: true });
22
+ const outputPath = node_path.default.join(outDir, "index.ts");
23
+ const fileContent = buildBarrelContent(iconNames, banner, style);
24
+ await node_fs_promises.default.writeFile(outputPath, fileContent, "utf-8");
25
+ return outputPath;
26
+ }
27
+
28
+ //#endregion
29
+ exports.writeBarrelFile = writeBarrelFile;