@featherk/icons 0.14.1 → 0.15.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,224 @@
1
+ const entries = [
2
+ {
3
+ key: "rocket",
4
+ name: "rocket",
5
+ version: "7.0.0",
6
+ family: "classic",
7
+ style: "solid",
8
+ package: "@fortawesome/free-solid-svg-icons",
9
+ registryPackage: "@fortawesome/free-solid-svg-icons",
10
+ exportName: "faRocket",
11
+ tier: "free"
12
+ },
13
+ {
14
+ key: "feather",
15
+ name: "feather",
16
+ version: "7.0.0",
17
+ family: "classic",
18
+ style: "solid",
19
+ package: "@fortawesome/free-solid-svg-icons",
20
+ registryPackage: "@fortawesome/free-solid-svg-icons",
21
+ exportName: "faFeather",
22
+ tier: "free"
23
+ },
24
+ {
25
+ key: "heart",
26
+ name: "heart",
27
+ version: "7.0.0",
28
+ family: "classic",
29
+ style: "solid",
30
+ package: "@fortawesome/free-solid-svg-icons",
31
+ registryPackage: "@fortawesome/free-solid-svg-icons",
32
+ exportName: "faHeart",
33
+ tier: "free"
34
+ },
35
+ {
36
+ key: "star",
37
+ name: "star",
38
+ version: "7.0.0",
39
+ family: "classic",
40
+ style: "solid",
41
+ package: "@fortawesome/free-solid-svg-icons",
42
+ registryPackage: "@fortawesome/free-solid-svg-icons",
43
+ exportName: "faStar",
44
+ tier: "free"
45
+ },
46
+ {
47
+ key: "user",
48
+ name: "user",
49
+ version: "7.0.0",
50
+ family: "classic",
51
+ style: "solid",
52
+ package: "@fortawesome/free-solid-svg-icons",
53
+ registryPackage: "@fortawesome/free-solid-svg-icons",
54
+ exportName: "faUser",
55
+ tier: "free"
56
+ },
57
+ {
58
+ key: "rocket-v5",
59
+ name: "rocket",
60
+ version: "5.15.4",
61
+ family: "classic",
62
+ style: "solid",
63
+ package: "fa-solid-v5",
64
+ registryPackage: "@fortawesome/free-solid-svg-icons",
65
+ exportName: "faRocket",
66
+ tier: "free"
67
+ },
68
+ {
69
+ key: "rocket-v6",
70
+ name: "rocket",
71
+ version: "6.7.2",
72
+ family: "classic",
73
+ style: "solid",
74
+ package: "fa-solid-v6",
75
+ registryPackage: "@fortawesome/free-solid-svg-icons",
76
+ exportName: "faRocket",
77
+ tier: "free"
78
+ },
79
+ {
80
+ key: "heart-regular",
81
+ name: "heart",
82
+ version: "7.0.0",
83
+ family: "classic",
84
+ style: "regular",
85
+ package: "@fortawesome/free-regular-svg-icons",
86
+ registryPackage: "@fortawesome/free-regular-svg-icons",
87
+ exportName: "faHeart",
88
+ tier: "free"
89
+ },
90
+ {
91
+ key: "star-regular",
92
+ name: "star",
93
+ version: "7.0.0",
94
+ family: "classic",
95
+ style: "regular",
96
+ package: "@fortawesome/free-regular-svg-icons",
97
+ registryPackage: "@fortawesome/free-regular-svg-icons",
98
+ exportName: "faStar",
99
+ tier: "free"
100
+ },
101
+ {
102
+ key: "user-regular",
103
+ name: "user",
104
+ version: "7.0.0",
105
+ family: "classic",
106
+ style: "regular",
107
+ package: "@fortawesome/free-regular-svg-icons",
108
+ registryPackage: "@fortawesome/free-regular-svg-icons",
109
+ exportName: "faUser",
110
+ tier: "free"
111
+ },
112
+ {
113
+ key: "pro-rocket-regular",
114
+ name: "rocket",
115
+ version: "7.0.0",
116
+ family: "classic",
117
+ style: "regular",
118
+ package: "@fortawesome/pro-regular-svg-icons",
119
+ registryPackage: "@fortawesome/pro-regular-svg-icons",
120
+ exportName: "faRocket",
121
+ tier: "pro"
122
+ },
123
+ {
124
+ key: "pro-feather-light",
125
+ name: "feather",
126
+ version: "7.0.0",
127
+ family: "classic",
128
+ style: "light",
129
+ package: "@fortawesome/pro-light-svg-icons",
130
+ registryPackage: "@fortawesome/pro-light-svg-icons",
131
+ exportName: "faFeather",
132
+ tier: "pro"
133
+ },
134
+ {
135
+ key: "pro-heart-light",
136
+ name: "heart",
137
+ version: "7.0.0",
138
+ family: "classic",
139
+ style: "light",
140
+ package: "@fortawesome/pro-light-svg-icons",
141
+ registryPackage: "@fortawesome/pro-light-svg-icons",
142
+ exportName: "faHeart",
143
+ tier: "pro"
144
+ },
145
+ {
146
+ key: "pro-house-light",
147
+ name: "house",
148
+ version: "7.0.0",
149
+ family: "classic",
150
+ style: "light",
151
+ package: "@fortawesome/pro-light-svg-icons",
152
+ registryPackage: "@fortawesome/pro-light-svg-icons",
153
+ exportName: "faHouse",
154
+ tier: "pro"
155
+ }
156
+ ];
157
+ function createCatalogIndex(catalog) {
158
+ const index = /* @__PURE__ */ new Map();
159
+ for (const entry of catalog) {
160
+ if (!entry.key.trim()) {
161
+ throw new Error("Font Awesome catalog keys must not be empty");
162
+ }
163
+ if (index.has(entry.key)) {
164
+ throw new Error(`Duplicate Font Awesome catalog key "${entry.key}"`);
165
+ }
166
+ index.set(entry.key, entry);
167
+ }
168
+ return index;
169
+ }
170
+ const fontAwesomeCatalog = Object.freeze(
171
+ entries.map((entry) => Object.freeze(entry))
172
+ );
173
+ const catalogByKey = createCatalogIndex(fontAwesomeCatalog);
174
+ function resolveFontAwesomeKeys(keys, options = {}) {
175
+ if (!Array.isArray(keys)) {
176
+ throw new Error("Font Awesome keys must be an array");
177
+ }
178
+ const seen = /* @__PURE__ */ new Set();
179
+ return keys.map((key) => {
180
+ if (typeof key !== "string" || !key.trim()) {
181
+ throw new Error("Font Awesome keys must be non-empty strings");
182
+ }
183
+ if (seen.has(key)) {
184
+ throw new Error(`Duplicate Font Awesome key "${key}"`);
185
+ }
186
+ seen.add(key);
187
+ const entry = catalogByKey.get(key);
188
+ if (!entry) {
189
+ throw new Error(`Unknown Font Awesome catalog key "${key}"`);
190
+ }
191
+ if (entry.tier === "pro" && !options.allowPro) {
192
+ throw new Error(
193
+ `Font Awesome key "${key}" is Pro; enable the Pro profile to use it`
194
+ );
195
+ }
196
+ return {
197
+ key: entry.key,
198
+ name: entry.name,
199
+ version: entry.version,
200
+ family: entry.family,
201
+ style: entry.style,
202
+ package: entry.package,
203
+ exportName: entry.exportName,
204
+ registryPackage: entry.registryPackage
205
+ };
206
+ });
207
+ }
208
+ function getFontAwesomeInstallCommand(keys, options = {}) {
209
+ resolveFontAwesomeKeys(keys, options);
210
+ const packages = /* @__PURE__ */ new Set();
211
+ for (const key of keys) {
212
+ const entry = catalogByKey.get(key);
213
+ packages.add(
214
+ entry.package === entry.registryPackage ? `${entry.registryPackage}@${entry.version}` : `${entry.package}@npm:${entry.registryPackage}@${entry.version}`
215
+ );
216
+ }
217
+ if (packages.size === 0) return void 0;
218
+ return `npm install --save-dev --save-exact ${[...packages].join(" ")}`;
219
+ }
220
+ export {
221
+ fontAwesomeCatalog,
222
+ getFontAwesomeInstallCommand,
223
+ resolveFontAwesomeKeys
224
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -3,6 +3,7 @@ const node_module = require("node:module");
3
3
  const promises = require("node:fs/promises");
4
4
  const node_path = require("node:path");
5
5
  const node_crypto = require("node:crypto");
6
+ const fontawesome_catalog = require("../catalog.cjs");
6
7
  const prefixes = {
7
8
  "classic:solid": "fas",
8
9
  "classic:regular": "far",
@@ -173,23 +174,30 @@ async function writeAtomically(file, content) {
173
174
  }
174
175
  }
175
176
  async function generateFaIcons(options) {
176
- const root = await promises.realpath(node_path.resolve(options.root ?? process.cwd()));
177
- if (!Array.isArray(options.icons))
178
- throw new Error("Font Awesome icons must be an array of selections");
179
- const selections = options.icons.map((selection) => {
180
- if (!selection || typeof selection !== "object") {
181
- throw new Error("Font Awesome selections must be objects");
182
- }
183
- return {
184
- key: selection.key,
185
- name: selection.name,
186
- version: selection.version,
187
- family: selection.family,
188
- style: selection.style,
189
- package: selection.package,
190
- ...selection.exportName === void 0 ? {} : { exportName: selection.exportName }
191
- };
177
+ const selections = fontawesome_catalog.resolveFontAwesomeKeys(options.keys, {
178
+ allowPro: options.allowPro
179
+ });
180
+ return generateFaIconsFromSelections({
181
+ root: options.root,
182
+ sourceRoot: options.sourceRoot,
183
+ allowPro: options.allowPro,
184
+ outFile: options.outFile,
185
+ virtualTypesFile: options.virtualTypesFile,
186
+ selections
192
187
  });
188
+ }
189
+ async function generateFaIconsFromSelections(options) {
190
+ const root = await promises.realpath(node_path.resolve(options.root ?? process.cwd()));
191
+ const selections = options.selections.map((selection) => ({
192
+ key: selection.key,
193
+ name: selection.name,
194
+ version: selection.version,
195
+ family: selection.family,
196
+ style: selection.style,
197
+ package: selection.package,
198
+ registryPackage: selection.registryPackage,
199
+ ...selection.exportName === void 0 ? {} : { exportName: selection.exportName }
200
+ }));
193
201
  const keys = /* @__PURE__ */ new Set();
194
202
  const exports$1 = selections.map((selection) => {
195
203
  const exportName = validateSelection(selection);
@@ -227,13 +235,23 @@ async function generateFaIcons(options) {
227
235
  );
228
236
  }
229
237
  const metadata = JSON.parse(await promises.readFile(metadataFile, "utf8"));
238
+ if (typeof metadata.name !== "string" || !metadata.name) {
239
+ throw new Error(`Missing source package name for "${selection.key}"`);
240
+ }
241
+ if (selection.registryPackage !== void 0 && metadata.name !== selection.registryPackage) {
242
+ throw new Error(
243
+ `Font Awesome package mismatch for "${selection.key}": expected ${selection.registryPackage}, installed ${metadata.name}`
244
+ );
245
+ }
230
246
  if (metadata.version !== selection.version) {
231
247
  throw new Error(
232
248
  `Font Awesome version mismatch for "${selection.key}": requested ${selection.version}, installed ${metadata.version}`
233
249
  );
234
250
  }
235
- if (typeof metadata.name !== "string" || !metadata.name) {
236
- throw new Error(`Missing source package name for "${selection.key}"`);
251
+ if (!options.allowPro && (selection.package.startsWith("@fortawesome/pro-") || metadata.name.startsWith("@fortawesome/pro-"))) {
252
+ throw new Error(
253
+ `Font Awesome source for "${selection.key}" is Pro; enable the Pro profile to use it`
254
+ );
237
255
  }
238
256
  const licenseFile = node_path.join(node_path.dirname(metadataFile), "LICENSE.txt");
239
257
  if (!notices.has(metadataFile)) {
@@ -258,7 +276,16 @@ ${text.trim()}
258
276
  );
259
277
  }
260
278
  icons[selection.key] = normalizeIcon(selection, source[exportName]);
261
- provenance.push({ ...selection, exportName, sourcePackage: metadata.name });
279
+ provenance.push({
280
+ key: selection.key,
281
+ name: selection.name,
282
+ version: selection.version,
283
+ family: selection.family,
284
+ style: selection.style,
285
+ package: selection.package,
286
+ exportName,
287
+ sourcePackage: metadata.name
288
+ });
262
289
  }
263
290
  const result = {
264
291
  moduleCode: `import { createFontAwesomeService } from "@featherk/icons/fontawesome";
@@ -2,6 +2,7 @@ import { createRequire } from "node:module";
2
2
  import { realpath, readFile, mkdir, writeFile, rename, unlink } from "node:fs/promises";
3
3
  import { resolve, join, dirname, relative, isAbsolute, sep, extname, basename } from "node:path";
4
4
  import { randomUUID } from "node:crypto";
5
+ import { resolveFontAwesomeKeys } from "../catalog.mjs";
5
6
  const prefixes = {
6
7
  "classic:solid": "fas",
7
8
  "classic:regular": "far",
@@ -172,23 +173,30 @@ async function writeAtomically(file, content) {
172
173
  }
173
174
  }
174
175
  async function generateFaIcons(options) {
175
- const root = await realpath(resolve(options.root ?? process.cwd()));
176
- if (!Array.isArray(options.icons))
177
- throw new Error("Font Awesome icons must be an array of selections");
178
- const selections = options.icons.map((selection) => {
179
- if (!selection || typeof selection !== "object") {
180
- throw new Error("Font Awesome selections must be objects");
181
- }
182
- return {
183
- key: selection.key,
184
- name: selection.name,
185
- version: selection.version,
186
- family: selection.family,
187
- style: selection.style,
188
- package: selection.package,
189
- ...selection.exportName === void 0 ? {} : { exportName: selection.exportName }
190
- };
176
+ const selections = resolveFontAwesomeKeys(options.keys, {
177
+ allowPro: options.allowPro
178
+ });
179
+ return generateFaIconsFromSelections({
180
+ root: options.root,
181
+ sourceRoot: options.sourceRoot,
182
+ allowPro: options.allowPro,
183
+ outFile: options.outFile,
184
+ virtualTypesFile: options.virtualTypesFile,
185
+ selections
191
186
  });
187
+ }
188
+ async function generateFaIconsFromSelections(options) {
189
+ const root = await realpath(resolve(options.root ?? process.cwd()));
190
+ const selections = options.selections.map((selection) => ({
191
+ key: selection.key,
192
+ name: selection.name,
193
+ version: selection.version,
194
+ family: selection.family,
195
+ style: selection.style,
196
+ package: selection.package,
197
+ registryPackage: selection.registryPackage,
198
+ ...selection.exportName === void 0 ? {} : { exportName: selection.exportName }
199
+ }));
192
200
  const keys = /* @__PURE__ */ new Set();
193
201
  const exports$1 = selections.map((selection) => {
194
202
  const exportName = validateSelection(selection);
@@ -226,13 +234,23 @@ async function generateFaIcons(options) {
226
234
  );
227
235
  }
228
236
  const metadata = JSON.parse(await readFile(metadataFile, "utf8"));
237
+ if (typeof metadata.name !== "string" || !metadata.name) {
238
+ throw new Error(`Missing source package name for "${selection.key}"`);
239
+ }
240
+ if (selection.registryPackage !== void 0 && metadata.name !== selection.registryPackage) {
241
+ throw new Error(
242
+ `Font Awesome package mismatch for "${selection.key}": expected ${selection.registryPackage}, installed ${metadata.name}`
243
+ );
244
+ }
229
245
  if (metadata.version !== selection.version) {
230
246
  throw new Error(
231
247
  `Font Awesome version mismatch for "${selection.key}": requested ${selection.version}, installed ${metadata.version}`
232
248
  );
233
249
  }
234
- if (typeof metadata.name !== "string" || !metadata.name) {
235
- throw new Error(`Missing source package name for "${selection.key}"`);
250
+ if (!options.allowPro && (selection.package.startsWith("@fortawesome/pro-") || metadata.name.startsWith("@fortawesome/pro-"))) {
251
+ throw new Error(
252
+ `Font Awesome source for "${selection.key}" is Pro; enable the Pro profile to use it`
253
+ );
236
254
  }
237
255
  const licenseFile = join(dirname(metadataFile), "LICENSE.txt");
238
256
  if (!notices.has(metadataFile)) {
@@ -257,7 +275,16 @@ ${text.trim()}
257
275
  );
258
276
  }
259
277
  icons[selection.key] = normalizeIcon(selection, source[exportName]);
260
- provenance.push({ ...selection, exportName, sourcePackage: metadata.name });
278
+ provenance.push({
279
+ key: selection.key,
280
+ name: selection.name,
281
+ version: selection.version,
282
+ family: selection.family,
283
+ style: selection.style,
284
+ package: selection.package,
285
+ exportName,
286
+ sourcePackage: metadata.name
287
+ });
261
288
  }
262
289
  const result = {
263
290
  moduleCode: `import { createFontAwesomeService } from "@featherk/icons/fontawesome";
@@ -3,10 +3,12 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const promises = require("node:fs/promises");
4
4
  const node_path = require("node:path");
5
5
  const node_util = require("node:util");
6
- const generate = require("./chunks/generate-Bobf_ghm.cjs");
7
- const usage = `Usage: featherk-fontawesome --manifest <icons.json> [--root <project>] [--source-root <installed-sources>] [--out <icons.mjs>] [--virtual-types <types.d.ts>]
6
+ const fontawesome_catalog = require("./catalog.cjs");
7
+ const generate = require("./chunks/generate-BBurrhLv.cjs");
8
+ const usage = `Usage: featherk-fontawesome --manifest <icons.json> [--root <project>] [--source-root <installed-sources>] [--allow-pro] [--out <icons.mjs>] [--virtual-types <types.d.ts>]
8
9
 
9
- The JSON manifest must contain { "icons": [...] } with exact installed selections.
10
+ The JSON manifest contains { "free": [keys], "pro": [keys] }.
11
+ Use --allow-pro to include Pro keys.
10
12
  Provide --out, --virtual-types, or both. Paths are relative to the project root.
11
13
  This command does not download assets or authenticate; install licensed packages first.
12
14
  Generated assets belong to the consuming project, never the @featherk/icons package.`;
@@ -20,6 +22,7 @@ async function runFontAwesomeCli(args, io = {}) {
20
22
  manifest: { type: "string" },
21
23
  root: { type: "string" },
22
24
  "source-root": { type: "string" },
25
+ "allow-pro": { type: "boolean" },
23
26
  out: { type: "string" },
24
27
  "virtual-types": { type: "string" },
25
28
  help: { type: "boolean", short: "h" }
@@ -40,18 +43,39 @@ async function runFontAwesomeCli(args, io = {}) {
40
43
  const manifest = JSON.parse(
41
44
  await promises.readFile(node_path.resolve(root, values.manifest), "utf8")
42
45
  );
43
- if (!manifest || typeof manifest !== "object" || Array.isArray(manifest) || !Array.isArray(manifest.icons)) {
44
- throw new Error(
45
- 'Font Awesome manifest must be a JSON object with an "icons" array'
46
- );
46
+ if (!manifest || typeof manifest !== "object" || Array.isArray(manifest)) {
47
+ throw new Error("Font Awesome manifest must be a JSON object");
47
48
  }
48
- const result = await generate.generateFaIcons({
49
+ const record = manifest;
50
+ const common = {
49
51
  root,
50
52
  sourceRoot: values["source-root"],
51
- icons: manifest.icons,
53
+ allowPro: values["allow-pro"],
52
54
  outFile: values.out,
53
55
  virtualTypesFile: values["virtual-types"]
56
+ };
57
+ const isKeyList = (value) => Array.isArray(value) && value.every((key) => typeof key === "string");
58
+ const freeKeys = record.free;
59
+ const proKeys = record.pro;
60
+ if (!isKeyList(freeKeys) || proKeys !== void 0 && !isKeyList(proKeys)) {
61
+ throw new Error(
62
+ 'Font Awesome manifest must contain "free" and optional "pro" key arrays'
63
+ );
64
+ }
65
+ const keys = [
66
+ ...freeKeys,
67
+ ...values["allow-pro"] ? proKeys ?? [] : []
68
+ ];
69
+ const installCommand = fontawesome_catalog.getFontAwesomeInstallCommand(keys, {
70
+ allowPro: values["allow-pro"]
54
71
  });
72
+ if (installCommand) {
73
+ stdout(
74
+ `Install selected Font Awesome source packages with:
75
+ ${installCommand}`
76
+ );
77
+ }
78
+ const result = await generate.generateFaIcons({ ...common, keys });
55
79
  stdout(
56
80
  `Prepared ${result.provenance.length} selected Font Awesome icon(s). Preserve generated license notices in application distribution.`
57
81
  );
@@ -1,6 +1,13 @@
1
+ /** Injectable process I/O used by the CLI entry point and its tests. */
1
2
  export interface FontAwesomeCliIO {
2
3
  cwd?: string;
3
4
  stdout?: (message: string) => void;
4
5
  stderr?: (message: string) => void;
5
6
  }
7
+ /**
8
+ * Parses CLI arguments and generates the requested consumer output.
9
+ *
10
+ * @returns `0` on success and `1` when argument, manifest, source, or output
11
+ * validation fails.
12
+ */
6
13
  export declare function runFontAwesomeCli(args: readonly string[], io?: FontAwesomeCliIO): Promise<number>;
@@ -1,10 +1,12 @@
1
1
  import { readFile } from "node:fs/promises";
2
2
  import { resolve } from "node:path";
3
3
  import { parseArgs } from "node:util";
4
- import { g as generateFaIcons } from "./chunks/generate-Bp92GTVi.mjs";
5
- const usage = `Usage: featherk-fontawesome --manifest <icons.json> [--root <project>] [--source-root <installed-sources>] [--out <icons.mjs>] [--virtual-types <types.d.ts>]
4
+ import { getFontAwesomeInstallCommand } from "./catalog.mjs";
5
+ import { g as generateFaIcons } from "./chunks/generate-Zq9q2YZD.mjs";
6
+ const usage = `Usage: featherk-fontawesome --manifest <icons.json> [--root <project>] [--source-root <installed-sources>] [--allow-pro] [--out <icons.mjs>] [--virtual-types <types.d.ts>]
6
7
 
7
- The JSON manifest must contain { "icons": [...] } with exact installed selections.
8
+ The JSON manifest contains { "free": [keys], "pro": [keys] }.
9
+ Use --allow-pro to include Pro keys.
8
10
  Provide --out, --virtual-types, or both. Paths are relative to the project root.
9
11
  This command does not download assets or authenticate; install licensed packages first.
10
12
  Generated assets belong to the consuming project, never the @featherk/icons package.`;
@@ -18,6 +20,7 @@ async function runFontAwesomeCli(args, io = {}) {
18
20
  manifest: { type: "string" },
19
21
  root: { type: "string" },
20
22
  "source-root": { type: "string" },
23
+ "allow-pro": { type: "boolean" },
21
24
  out: { type: "string" },
22
25
  "virtual-types": { type: "string" },
23
26
  help: { type: "boolean", short: "h" }
@@ -38,18 +41,39 @@ async function runFontAwesomeCli(args, io = {}) {
38
41
  const manifest = JSON.parse(
39
42
  await readFile(resolve(root, values.manifest), "utf8")
40
43
  );
41
- if (!manifest || typeof manifest !== "object" || Array.isArray(manifest) || !Array.isArray(manifest.icons)) {
42
- throw new Error(
43
- 'Font Awesome manifest must be a JSON object with an "icons" array'
44
- );
44
+ if (!manifest || typeof manifest !== "object" || Array.isArray(manifest)) {
45
+ throw new Error("Font Awesome manifest must be a JSON object");
45
46
  }
46
- const result = await generateFaIcons({
47
+ const record = manifest;
48
+ const common = {
47
49
  root,
48
50
  sourceRoot: values["source-root"],
49
- icons: manifest.icons,
51
+ allowPro: values["allow-pro"],
50
52
  outFile: values.out,
51
53
  virtualTypesFile: values["virtual-types"]
54
+ };
55
+ const isKeyList = (value) => Array.isArray(value) && value.every((key) => typeof key === "string");
56
+ const freeKeys = record.free;
57
+ const proKeys = record.pro;
58
+ if (!isKeyList(freeKeys) || proKeys !== void 0 && !isKeyList(proKeys)) {
59
+ throw new Error(
60
+ 'Font Awesome manifest must contain "free" and optional "pro" key arrays'
61
+ );
62
+ }
63
+ const keys = [
64
+ ...freeKeys,
65
+ ...values["allow-pro"] ? proKeys ?? [] : []
66
+ ];
67
+ const installCommand = getFontAwesomeInstallCommand(keys, {
68
+ allowPro: values["allow-pro"]
52
69
  });
70
+ if (installCommand) {
71
+ stdout(
72
+ `Install selected Font Awesome source packages with:
73
+ ${installCommand}`
74
+ );
75
+ }
76
+ const result = await generateFaIcons({ ...common, keys });
53
77
  stdout(
54
78
  `Prepared ${result.provenance.length} selected Font Awesome icon(s). Preserve generated license notices in application distribution.`
55
79
  );
@@ -1,12 +1,22 @@
1
- import type { FontAwesomeOptions, FontAwesomeSelection } from "./types";
1
+ import type { FontAwesomeOptions, FontAwesomeSelection, FontAwesomeSourceSelection } from "./types";
2
+ /** Options for resolving selected Font Awesome icons into consumer output. */
2
3
  export interface GenerateFaIconsOptions extends FontAwesomeOptions {
3
4
  outFile?: string;
4
5
  virtualTypesFile?: string;
5
6
  }
7
+ /**
8
+ * Resolved source selections for the internal generation core.
9
+ * @internal
10
+ */
11
+ export interface GenerateFaIconsFromSelectionsOptions extends Omit<GenerateFaIconsOptions, "keys"> {
12
+ selections: readonly FontAwesomeSourceSelection[];
13
+ }
14
+ /** Source identity used to generate one selected icon. */
6
15
  export interface FontAwesomeProvenance extends FontAwesomeSelection {
7
16
  sourcePackage: string;
8
17
  exportName: string;
9
18
  }
19
+ /** Files and metadata produced while generating a consumer icon module. */
10
20
  export interface GeneratedFaIcons {
11
21
  moduleCode: string;
12
22
  declarationCode: string;
@@ -15,4 +25,18 @@ export interface GeneratedFaIcons {
15
25
  provenance: readonly FontAwesomeProvenance[];
16
26
  dependencies: readonly string[];
17
27
  }
28
+ /**
29
+ * Generates descriptors for the requested catalog keys.
30
+ *
31
+ * Catalog-key selections verify the installed package name and exact version
32
+ * before loading its icon export. Pro keys require `allowPro: true`.
33
+ *
34
+ * @throws If a key is unknown or duplicated, a Pro key is not opted into, an
35
+ * installed source does not match the requested identity, or output is unsafe.
36
+ */
18
37
  export declare function generateFaIcons(options: GenerateFaIconsOptions): Promise<GeneratedFaIcons>;
38
+ /**
39
+ * Generates descriptors from already-resolved source selections.
40
+ * @internal
41
+ */
42
+ export declare function generateFaIconsFromSelections(options: GenerateFaIconsFromSelectionsOptions): Promise<GeneratedFaIcons>;
@@ -1,3 +1,13 @@
1
+ /**
2
+ * Validates installed Font Awesome definitions and converts safe path geometry
3
+ * into the Kendo-compatible SVG icon descriptor used by the runtime service.
4
+ */
1
5
  import type { FontAwesomeIcon, FontAwesomeSelection } from "./types";
6
+ /** Returns the required Font Awesome prefix for a catalog family/style pair. */
2
7
  export declare function expectedPrefix(selection: FontAwesomeSelection): string;
8
+ /**
9
+ * Validates a selected icon definition and normalizes its paths and viewBox.
10
+ *
11
+ * @throws If the identity, geometry, layer count, or path data is invalid.
12
+ */
3
13
  export declare function normalizeIcon(selection: FontAwesomeSelection, definition: unknown): FontAwesomeIcon;
@@ -5,6 +5,7 @@ export interface FontAwesomeIcon {
5
5
  }
6
6
  export type FontAwesomeFamily = "classic" | "sharp" | "duotone" | "sharp-duotone";
7
7
  export type FontAwesomeStyle = "solid" | "regular" | "light" | "thin" | "brands";
8
+ export type FontAwesomeTier = "free" | "pro";
8
9
  export interface FontAwesomeSelection {
9
10
  key: string;
10
11
  name: string;
@@ -14,8 +15,17 @@ export interface FontAwesomeSelection {
14
15
  package: string;
15
16
  exportName?: string;
16
17
  }
18
+ export interface FontAwesomeSourceSelection extends FontAwesomeSelection {
19
+ registryPackage: string;
20
+ }
21
+ export interface FontAwesomeCatalogEntry extends FontAwesomeSelection {
22
+ exportName: string;
23
+ registryPackage: string;
24
+ tier: FontAwesomeTier;
25
+ }
17
26
  export interface FontAwesomeOptions {
18
- icons: readonly FontAwesomeSelection[];
27
+ keys: readonly string[];
19
28
  root?: string;
20
29
  sourceRoot?: string;
30
+ allowPro?: boolean;
21
31
  }