@featherk/icons 0.15.7 → 0.16.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 (39) hide show
  1. package/README.md +15 -3
  2. package/bin/featherk-fontawesome-setup.mjs +4 -0
  3. package/dist/docs-manifest.d.ts +1 -0
  4. package/dist/docs-manifest.js +7 -5
  5. package/dist/fontawesome/build.cjs +1 -2
  6. package/dist/fontawesome/build.d.ts +1 -1
  7. package/dist/fontawesome/build.mjs +2 -3
  8. package/dist/fontawesome/catalog.cjs +0 -13
  9. package/dist/fontawesome/catalog.d.ts +0 -8
  10. package/dist/fontawesome/catalog.mjs +0 -13
  11. package/dist/fontawesome/chunks/{generate-BBurrhLv.cjs → generate-B_FxftR7.cjs} +12 -1
  12. package/dist/fontawesome/chunks/{generate-Zq9q2YZD.mjs → generate-DF9R65sV.mjs} +13 -2
  13. package/dist/fontawesome/chunks/manifest-CSRIDvaR.mjs +56 -0
  14. package/dist/fontawesome/chunks/manifest-Yjw62jxG.cjs +55 -0
  15. package/dist/fontawesome/cli.cjs +25 -40
  16. package/dist/fontawesome/cli.mjs +25 -40
  17. package/dist/fontawesome/generate.d.ts +7 -0
  18. package/dist/fontawesome/manifest.d.ts +50 -0
  19. package/dist/fontawesome/setup.cjs +482 -0
  20. package/dist/fontawesome/setup.d.ts +39 -0
  21. package/dist/fontawesome/setup.mjs +482 -0
  22. package/dist/fontawesome/vite.cjs +64 -28
  23. package/dist/fontawesome/vite.d.ts +26 -5
  24. package/dist/fontawesome/vite.mjs +65 -29
  25. package/docs/ICONS.md +1 -1
  26. package/docs/fontawesome/CreateFontAwesomeManifest.md +1 -1
  27. package/docs/fontawesome/FontAwesome.md +48 -44
  28. package/docs/fontawesome/FontAwesomeCLI.md +14 -17
  29. package/docs/fontawesome/FontAwesomeDeveloperSetup.md +134 -0
  30. package/docs/fontawesome/LICENSING.md +185 -26
  31. package/package.json +5 -4
  32. package/dist/fontawesome/catalog.test.d.ts +0 -1
  33. package/dist/fontawesome/cli.test.d.ts +0 -1
  34. package/dist/fontawesome/fontawesome-service.test.d.ts +0 -1
  35. package/dist/fontawesome/generate.test.d.ts +0 -1
  36. package/dist/fontawesome/normalize.test.d.ts +0 -1
  37. package/dist/fontawesome/vite.test.d.ts +0 -1
  38. package/dist/icon-service.test.d.ts +0 -1
  39. /package/{scripts/fontawesome.mjs → bin/featherk-fontawesome.mjs} +0 -0
package/README.md CHANGED
@@ -68,11 +68,23 @@ variants, data URL usage, and related utilities) see [COMING-SOON.md](docs/COMIN
68
68
 
69
69
  ## Font Awesome Build Integration
70
70
 
71
- Font Awesome services are separate from `getCustomIcon()` and the owned icon registry. The package supplies a Vite plugin, Node generator, and CLI to prepare selected icons from the consumer's installed Font Awesome packages; it includes no Free or paid Font Awesome artwork and grants no license rights.
71
+ Font Awesome services are separate from `getCustomIcon()` and the owned icon registry. They generate selected icons from the consumer's installed Font Awesome packages; the package includes no Free or paid Font Awesome artwork and grants no license rights.
72
72
 
73
- Start with [Choose Font Awesome Icons and Create a Manifest](https://github.com/NantHealth/featherk/blob/integration/packages/icons/docs/fontawesome/CreateFontAwesomeManifest.md) for how UX provides globally unique catalog keys and apps select only the keys they use. The metadata-only Free/Pro catalog is published at `@featherk/icons/fontawesome/catalog`; it contains no Font Awesome artwork.
73
+ One keys-only manifest drives the whole setup:
74
74
 
75
- Dev then follows [Font Awesome setup](https://github.com/NantHealth/featherk/blob/integration/packages/icons/docs/fontawesome/FontAwesome.md) for the default Vite integration. For Dev-owned CLI generation, early type preparation, or non-Vite applications, see [CLI and non-Vite setup](https://github.com/NantHealth/featherk/blob/integration/packages/icons/docs/fontawesome/FontAwesomeCLI.md).
75
+ ```sh
76
+ # 1. List UX-provided catalog keys in fontawesome.keys.json: { "free": [...], "pro": [...] }
77
+ # 2. Install exactly those source packages: Free into the app, Pro into fontawesome-pro-sources/.
78
+ # (Add --free-only when there are no Pro keys.)
79
+ npx featherk-fontawesome-setup --manifest fontawesome.keys.json
80
+ ```
81
+
82
+ ```ts
83
+ // 3. Generate them in vite.config.ts; builds include Pro icons wherever fontawesome-pro-sources/ is installed.
84
+ featherkFontAwesome({ manifest: "fontawesome.keys.json" });
85
+ ```
86
+
87
+ Follow [FeatherK FontAwesome Developer Setup](https://github.com/NantHealth/featherk/blob/integration/packages/icons/docs/fontawesome/FontAwesomeDeveloperSetup.md) for the step-by-step local and CI setup. See [Choose Font Awesome Icons and Create a Manifest](https://github.com/NantHealth/featherk/blob/integration/packages/icons/docs/fontawesome/CreateFontAwesomeManifest.md) for keys, and [Font Awesome setup](https://github.com/NantHealth/featherk/blob/integration/packages/icons/docs/fontawesome/FontAwesome.md) for the Quick Start and advanced setups. The metadata-only Free/Pro catalog is published at `@featherk/icons/fontawesome/catalog`.
76
88
 
77
89
  For paid source packages, see [Pro licensing and setup](https://github.com/NantHealth/featherk/blob/integration/packages/icons/docs/fontawesome/LICENSING.md). Pro access is consumer-owned and optional; no paid artwork is distributed by this package.
78
90
 
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+ import { runFontAwesomeSetup } from "../dist/fontawesome/setup.mjs";
3
+
4
+ process.exitCode = await runFontAwesomeSetup(process.argv.slice(2));
@@ -3,6 +3,7 @@ export type DocName =
3
3
  | "CreateFontAwesomeManifest"
4
4
  | "FontAwesome"
5
5
  | "FontAwesomeCLI"
6
+ | "FontAwesomeDeveloperSetup"
6
7
  | "LICENSING";
7
8
 
8
9
  export declare const packageName: "@featherk/icons";
@@ -1,20 +1,22 @@
1
1
  // Generated by scripts/generate-docs-manifest.mjs. Do not edit.
2
2
  export const packageName = "@featherk/icons";
3
3
 
4
- export const version = "0.15.7";
4
+ export const version = "0.16.0";
5
5
 
6
6
  export const paths = {
7
7
  CreateFontAwesomeManifest: "fontawesome/CreateFontAwesomeManifest.md",
8
8
  FontAwesome: "fontawesome/FontAwesome.md",
9
9
  FontAwesomeCLI: "fontawesome/FontAwesomeCLI.md",
10
+ FontAwesomeDeveloperSetup: "fontawesome/FontAwesomeDeveloperSetup.md",
10
11
  LICENSING: "fontawesome/LICENSING.md",
11
12
  };
12
13
 
13
14
  export const docs = {
14
- CreateFontAwesomeManifest: "https://cdn.jsdelivr.net/npm/@featherk/icons@0.15.7/docs/fontawesome/CreateFontAwesomeManifest.md",
15
- FontAwesome: "https://cdn.jsdelivr.net/npm/@featherk/icons@0.15.7/docs/fontawesome/FontAwesome.md",
16
- FontAwesomeCLI: "https://cdn.jsdelivr.net/npm/@featherk/icons@0.15.7/docs/fontawesome/FontAwesomeCLI.md",
17
- LICENSING: "https://cdn.jsdelivr.net/npm/@featherk/icons@0.15.7/docs/fontawesome/LICENSING.md",
15
+ CreateFontAwesomeManifest: "https://cdn.jsdelivr.net/npm/@featherk/icons@0.16.0/docs/fontawesome/CreateFontAwesomeManifest.md",
16
+ FontAwesome: "https://cdn.jsdelivr.net/npm/@featherk/icons@0.16.0/docs/fontawesome/FontAwesome.md",
17
+ FontAwesomeCLI: "https://cdn.jsdelivr.net/npm/@featherk/icons@0.16.0/docs/fontawesome/FontAwesomeCLI.md",
18
+ FontAwesomeDeveloperSetup: "https://cdn.jsdelivr.net/npm/@featherk/icons@0.16.0/docs/fontawesome/FontAwesomeDeveloperSetup.md",
19
+ LICENSING: "https://cdn.jsdelivr.net/npm/@featherk/icons@0.16.0/docs/fontawesome/LICENSING.md",
18
20
  };
19
21
 
20
22
  export const docUrl = (name, host = "https://cdn.jsdelivr.net/npm") =>
@@ -1,8 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const generate = require("./chunks/generate-BBurrhLv.cjs");
3
+ const generate = require("./chunks/generate-B_FxftR7.cjs");
4
4
  const fontawesome_catalog = require("./catalog.cjs");
5
5
  exports.generateFaIcons = generate.generateFaIcons;
6
6
  exports.fontAwesomeCatalog = fontawesome_catalog.fontAwesomeCatalog;
7
- exports.getFontAwesomeInstallCommand = fontawesome_catalog.getFontAwesomeInstallCommand;
8
7
  exports.resolveFontAwesomeKeys = fontawesome_catalog.resolveFontAwesomeKeys;
@@ -1,5 +1,5 @@
1
1
  export { generateFaIcons } from "./generate";
2
- export { fontAwesomeCatalog, getFontAwesomeInstallCommand, resolveFontAwesomeKeys, } from "./catalog";
2
+ export { fontAwesomeCatalog, resolveFontAwesomeKeys } from "./catalog";
3
3
  export type { GenerateFaIconsOptions, GeneratedFaIcons, FontAwesomeProvenance, } from "./generate";
4
4
  export type { FontAwesomeSelection, FontAwesomeOptions, FontAwesomeIcon, FontAwesomeCatalogEntry, FontAwesomeSourceSelection, FontAwesomeTier, } from "./types";
5
5
  export type { FontAwesomeCatalogKey, ResolveFontAwesomeKeysOptions, } from "./catalog";
@@ -1,8 +1,7 @@
1
- import { g } from "./chunks/generate-Zq9q2YZD.mjs";
2
- import { fontAwesomeCatalog, getFontAwesomeInstallCommand, resolveFontAwesomeKeys } from "./catalog.mjs";
1
+ import { g } from "./chunks/generate-DF9R65sV.mjs";
2
+ import { fontAwesomeCatalog, resolveFontAwesomeKeys } from "./catalog.mjs";
3
3
  export {
4
4
  fontAwesomeCatalog,
5
5
  g as generateFaIcons,
6
- getFontAwesomeInstallCommand,
7
6
  resolveFontAwesomeKeys
8
7
  };
@@ -207,18 +207,5 @@ function resolveFontAwesomeKeys(keys, options = {}) {
207
207
  };
208
208
  });
209
209
  }
210
- function getFontAwesomeInstallCommand(keys, options = {}) {
211
- resolveFontAwesomeKeys(keys, options);
212
- const packages = /* @__PURE__ */ new Set();
213
- for (const key of keys) {
214
- const entry = catalogByKey.get(key);
215
- packages.add(
216
- entry.package === entry.registryPackage ? `${entry.registryPackage}@${entry.version}` : `${entry.package}@npm:${entry.registryPackage}@${entry.version}`
217
- );
218
- }
219
- if (packages.size === 0) return void 0;
220
- return `npm install --save-dev --save-exact ${[...packages].join(" ")}`;
221
- }
222
210
  exports.fontAwesomeCatalog = fontAwesomeCatalog;
223
- exports.getFontAwesomeInstallCommand = getFontAwesomeInstallCommand;
224
211
  exports.resolveFontAwesomeKeys = resolveFontAwesomeKeys;
@@ -295,12 +295,4 @@ export interface ResolveFontAwesomeKeysOptions {
295
295
  * @throws If a key is empty, duplicated, unknown, or Pro without opt-in.
296
296
  */
297
297
  export declare function resolveFontAwesomeKeys(keys: readonly string[], options?: ResolveFontAwesomeKeysOptions): FontAwesomeSourceSelection[];
298
- /**
299
- * Builds a deduplicated exact npm install command for the selected keys.
300
- * Npm aliases are emitted when a local dependency name differs from its
301
- * canonical registry package. The command is informational and is not run.
302
- *
303
- * @returns An install command, or `undefined` when no keys are selected.
304
- */
305
- export declare function getFontAwesomeInstallCommand(keys: readonly string[], options?: ResolveFontAwesomeKeysOptions): string | undefined;
306
298
  export {};
@@ -205,20 +205,7 @@ function resolveFontAwesomeKeys(keys, options = {}) {
205
205
  };
206
206
  });
207
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
208
  export {
221
209
  fontAwesomeCatalog,
222
- getFontAwesomeInstallCommand,
223
210
  resolveFontAwesomeKeys
224
211
  };
@@ -173,6 +173,16 @@ async function writeAtomically(file, content) {
173
173
  });
174
174
  }
175
175
  }
176
+ function summarizeFaIcons(provenance) {
177
+ const packages = new Set(
178
+ provenance.map(
179
+ ({ package: name, sourcePackage, version }) => name === sourcePackage ? `${name}@${version}` : `${name} (${sourcePackage}@${version})`
180
+ )
181
+ );
182
+ const icons = `${provenance.length} Font Awesome icon(s)`;
183
+ return packages.size ? `${icons} from:
184
+ ${[...packages].map((name) => ` ${name}`).join("\n")}` : icons;
185
+ }
176
186
  async function generateFaIcons(options) {
177
187
  const selections = fontawesome_catalog.resolveFontAwesomeKeys(options.keys, {
178
188
  allowPro: options.allowPro
@@ -230,7 +240,7 @@ async function generateFaIconsFromSelections(options) {
230
240
  );
231
241
  } catch (error) {
232
242
  throw new Error(
233
- `Cannot resolve installed Font Awesome source "${selection.package}/${exportName}" for "${selection.key}". Install its pinned package and expose package.json and individual icon modules.`,
243
+ `Cannot resolve installed Font Awesome source "${selection.package}/${exportName}" for "${selection.key}". Install the manifest's pinned packages with "featherk-fontawesome-setup --manifest <manifest>" (or, after npm ci, "featherk-fontawesome-setup" for fontawesome-pro-sources/).`,
234
244
  { cause: error }
235
245
  );
236
246
  }
@@ -313,3 +323,4 @@ ${result.declarationCode.replaceAll("export declare ", "export ")}
313
323
  return result;
314
324
  }
315
325
  exports.generateFaIcons = generateFaIcons;
326
+ exports.summarizeFaIcons = summarizeFaIcons;
@@ -172,6 +172,16 @@ async function writeAtomically(file, content) {
172
172
  });
173
173
  }
174
174
  }
175
+ function summarizeFaIcons(provenance) {
176
+ const packages = new Set(
177
+ provenance.map(
178
+ ({ package: name, sourcePackage, version }) => name === sourcePackage ? `${name}@${version}` : `${name} (${sourcePackage}@${version})`
179
+ )
180
+ );
181
+ const icons = `${provenance.length} Font Awesome icon(s)`;
182
+ return packages.size ? `${icons} from:
183
+ ${[...packages].map((name) => ` ${name}`).join("\n")}` : icons;
184
+ }
175
185
  async function generateFaIcons(options) {
176
186
  const selections = resolveFontAwesomeKeys(options.keys, {
177
187
  allowPro: options.allowPro
@@ -229,7 +239,7 @@ async function generateFaIconsFromSelections(options) {
229
239
  );
230
240
  } catch (error) {
231
241
  throw new Error(
232
- `Cannot resolve installed Font Awesome source "${selection.package}/${exportName}" for "${selection.key}". Install its pinned package and expose package.json and individual icon modules.`,
242
+ `Cannot resolve installed Font Awesome source "${selection.package}/${exportName}" for "${selection.key}". Install the manifest's pinned packages with "featherk-fontawesome-setup --manifest <manifest>" (or, after npm ci, "featherk-fontawesome-setup" for fontawesome-pro-sources/).`,
233
243
  { cause: error }
234
244
  );
235
245
  }
@@ -312,5 +322,6 @@ ${result.declarationCode.replaceAll("export declare ", "export ")}
312
322
  return result;
313
323
  }
314
324
  export {
315
- generateFaIcons as g
325
+ generateFaIcons as g,
326
+ summarizeFaIcons as s
316
327
  };
@@ -0,0 +1,56 @@
1
+ import { existsSync } from "node:fs";
2
+ import { readFile } from "node:fs/promises";
3
+ import { join } from "node:path";
4
+ import { fontAwesomeCatalog } from "../catalog.mjs";
5
+ const isKeyList = (value) => Array.isArray(value) && value.every((key) => typeof key === "string");
6
+ function parseFontAwesomeManifest(manifest) {
7
+ if (!manifest || typeof manifest !== "object" || Array.isArray(manifest)) {
8
+ throw new Error("Font Awesome manifest must be a JSON object");
9
+ }
10
+ const { free, pro } = manifest;
11
+ if (!isKeyList(free) || pro !== void 0 && !isKeyList(pro)) {
12
+ throw new Error(
13
+ 'Font Awesome manifest must contain "free" and optional "pro" key arrays'
14
+ );
15
+ }
16
+ return { free, pro: pro ?? [] };
17
+ }
18
+ async function readFontAwesomeManifest(path) {
19
+ return parseFontAwesomeManifest(JSON.parse(await readFile(path, "utf8")));
20
+ }
21
+ const fontAwesomeProSourcesDir = "fontawesome-pro-sources";
22
+ function isFontAwesomeIsolated(root) {
23
+ return existsSync(join(root, fontAwesomeProSourcesDir, "package.json"));
24
+ }
25
+ function isFontAwesomeProInstalled(root) {
26
+ return existsSync(join(root, fontAwesomeProSourcesDir, "node_modules"));
27
+ }
28
+ const tiers = new Map(
29
+ fontAwesomeCatalog.map((entry) => [entry.key, entry.tier])
30
+ );
31
+ function fontAwesomeManifestKeys(manifest) {
32
+ const misplaced = manifest.free.filter((key) => tiers.get(key) === "pro");
33
+ if (misplaced.length) {
34
+ throw new Error(
35
+ `Font Awesome manifest lists Pro keys under "free"; move them to "pro": ${misplaced.join(", ")}`
36
+ );
37
+ }
38
+ return [...manifest.free, ...manifest.pro];
39
+ }
40
+ function selectFontAwesomeManifestKeys(manifest, root) {
41
+ const keys = fontAwesomeManifestKeys(manifest);
42
+ if (!isFontAwesomeIsolated(root)) {
43
+ return { keys, allowPro: true };
44
+ }
45
+ if (!isFontAwesomeProInstalled(root)) {
46
+ return { keys: manifest.free, allowPro: false };
47
+ }
48
+ return { keys, allowPro: true, sourceRoot: fontAwesomeProSourcesDir };
49
+ }
50
+ export {
51
+ fontAwesomeManifestKeys as a,
52
+ fontAwesomeProSourcesDir as f,
53
+ isFontAwesomeIsolated as i,
54
+ readFontAwesomeManifest as r,
55
+ selectFontAwesomeManifestKeys as s
56
+ };
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ const node_fs = require("node:fs");
3
+ const promises = require("node:fs/promises");
4
+ const node_path = require("node:path");
5
+ const fontawesome_catalog = require("../catalog.cjs");
6
+ const isKeyList = (value) => Array.isArray(value) && value.every((key) => typeof key === "string");
7
+ function parseFontAwesomeManifest(manifest) {
8
+ if (!manifest || typeof manifest !== "object" || Array.isArray(manifest)) {
9
+ throw new Error("Font Awesome manifest must be a JSON object");
10
+ }
11
+ const { free, pro } = manifest;
12
+ if (!isKeyList(free) || pro !== void 0 && !isKeyList(pro)) {
13
+ throw new Error(
14
+ 'Font Awesome manifest must contain "free" and optional "pro" key arrays'
15
+ );
16
+ }
17
+ return { free, pro: pro ?? [] };
18
+ }
19
+ async function readFontAwesomeManifest(path) {
20
+ return parseFontAwesomeManifest(JSON.parse(await promises.readFile(path, "utf8")));
21
+ }
22
+ const fontAwesomeProSourcesDir = "fontawesome-pro-sources";
23
+ function isFontAwesomeIsolated(root) {
24
+ return node_fs.existsSync(node_path.join(root, fontAwesomeProSourcesDir, "package.json"));
25
+ }
26
+ function isFontAwesomeProInstalled(root) {
27
+ return node_fs.existsSync(node_path.join(root, fontAwesomeProSourcesDir, "node_modules"));
28
+ }
29
+ const tiers = new Map(
30
+ fontawesome_catalog.fontAwesomeCatalog.map((entry) => [entry.key, entry.tier])
31
+ );
32
+ function fontAwesomeManifestKeys(manifest) {
33
+ const misplaced = manifest.free.filter((key) => tiers.get(key) === "pro");
34
+ if (misplaced.length) {
35
+ throw new Error(
36
+ `Font Awesome manifest lists Pro keys under "free"; move them to "pro": ${misplaced.join(", ")}`
37
+ );
38
+ }
39
+ return [...manifest.free, ...manifest.pro];
40
+ }
41
+ function selectFontAwesomeManifestKeys(manifest, root) {
42
+ const keys = fontAwesomeManifestKeys(manifest);
43
+ if (!isFontAwesomeIsolated(root)) {
44
+ return { keys, allowPro: true };
45
+ }
46
+ if (!isFontAwesomeProInstalled(root)) {
47
+ return { keys: manifest.free, allowPro: false };
48
+ }
49
+ return { keys, allowPro: true, sourceRoot: fontAwesomeProSourcesDir };
50
+ }
51
+ exports.fontAwesomeManifestKeys = fontAwesomeManifestKeys;
52
+ exports.fontAwesomeProSourcesDir = fontAwesomeProSourcesDir;
53
+ exports.isFontAwesomeIsolated = isFontAwesomeIsolated;
54
+ exports.readFontAwesomeManifest = readFontAwesomeManifest;
55
+ exports.selectFontAwesomeManifestKeys = selectFontAwesomeManifestKeys;
@@ -1,14 +1,16 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const promises = require("node:fs/promises");
4
3
  const node_path = require("node:path");
5
4
  const node_util = require("node:util");
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>]
5
+ const generate = require("./chunks/generate-B_FxftR7.cjs");
6
+ const manifest = require("./chunks/manifest-Yjw62jxG.cjs");
7
+ const usage = `Usage: featherk-fontawesome --manifest <icons.json> [--root <project>] [--out <icons.mjs>] [--virtual-types <types.d.ts>]
9
8
 
10
- The JSON manifest contains { "free": [keys], "pro": [keys] }.
11
- Use --allow-pro to include Pro keys.
9
+ The JSON manifest contains { "free": [keys], "pro": [keys] }, the same file
10
+ used by featherk-fontawesome-setup and the Vite plugin.
11
+ When the project has a ${manifest.fontAwesomeProSourcesDir}/ source project (the
12
+ default setup), Pro keys are generated from it only when it is installed.
13
+ Otherwise all keys are generated from the project's own installed sources.
12
14
  Provide --out, --virtual-types, or both. Paths are relative to the project root.
13
15
  This command does not download assets or authenticate; install licensed packages first.
14
16
  Generated assets belong to the consuming project, never the @featherk/icons package.`;
@@ -16,13 +18,19 @@ async function runFontAwesomeCli(args, io = {}) {
16
18
  const stdout = io.stdout ?? console.log;
17
19
  const stderr = io.stderr ?? console.error;
18
20
  try {
21
+ const removed = ["--allow-pro", "--source-root", "--pro-mode"].find(
22
+ (flag) => args.some((arg) => arg === flag || arg.startsWith(`${flag}=`))
23
+ );
24
+ if (removed) {
25
+ throw new Error(
26
+ `${removed} was removed in 0.16.0. Pro keys follow the manifest; Pro sources always live in ${manifest.fontAwesomeProSourcesDir}/ and are used wherever it is installed.`
27
+ );
28
+ }
19
29
  const { values } = node_util.parseArgs({
20
30
  args: [...args],
21
31
  options: {
22
32
  manifest: { type: "string" },
23
33
  root: { type: "string" },
24
- "source-root": { type: "string" },
25
- "allow-pro": { type: "boolean" },
26
34
  out: { type: "string" },
27
35
  "virtual-types": { type: "string" },
28
36
  help: { type: "boolean", short: "h" }
@@ -40,44 +48,21 @@ async function runFontAwesomeCli(args, io = {}) {
40
48
  );
41
49
  }
42
50
  const root = node_path.resolve(io.cwd ?? process.cwd(), values.root ?? ".");
43
- const manifest = JSON.parse(
44
- await promises.readFile(node_path.resolve(root, values.manifest), "utf8")
51
+ const manifest$1 = await manifest.readFontAwesomeManifest(
52
+ node_path.resolve(root, values.manifest)
45
53
  );
46
- if (!manifest || typeof manifest !== "object" || Array.isArray(manifest)) {
47
- throw new Error("Font Awesome manifest must be a JSON object");
48
- }
49
- const record = manifest;
50
- const common = {
54
+ const selection = manifest.selectFontAwesomeManifestKeys(manifest$1, root);
55
+ const result = await generate.generateFaIcons({
51
56
  root,
52
- sourceRoot: values["source-root"],
53
- allowPro: values["allow-pro"],
57
+ keys: selection.keys,
58
+ sourceRoot: selection.sourceRoot,
59
+ allowPro: selection.allowPro,
54
60
  outFile: values.out,
55
61
  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"]
71
62
  });
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 });
79
63
  stdout(
80
- `Prepared ${result.provenance.length} selected Font Awesome icon(s). Preserve generated license notices in application distribution.`
64
+ values.out ? `Prepared ${generate.summarizeFaIcons(result.provenance)}
65
+ Preserve generated license notices in application distribution.` : `Prepared declarations for ${result.provenance.length} Font Awesome icon(s).`
81
66
  );
82
67
  return 0;
83
68
  } catch (error) {
@@ -1,12 +1,14 @@
1
- import { readFile } from "node:fs/promises";
2
1
  import { resolve } from "node:path";
3
2
  import { parseArgs } from "node:util";
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>]
3
+ import { g as generateFaIcons, s as summarizeFaIcons } from "./chunks/generate-DF9R65sV.mjs";
4
+ import { f as fontAwesomeProSourcesDir, r as readFontAwesomeManifest, s as selectFontAwesomeManifestKeys } from "./chunks/manifest-CSRIDvaR.mjs";
5
+ const usage = `Usage: featherk-fontawesome --manifest <icons.json> [--root <project>] [--out <icons.mjs>] [--virtual-types <types.d.ts>]
7
6
 
8
- The JSON manifest contains { "free": [keys], "pro": [keys] }.
9
- Use --allow-pro to include Pro keys.
7
+ The JSON manifest contains { "free": [keys], "pro": [keys] }, the same file
8
+ used by featherk-fontawesome-setup and the Vite plugin.
9
+ When the project has a ${fontAwesomeProSourcesDir}/ source project (the
10
+ default setup), Pro keys are generated from it only when it is installed.
11
+ Otherwise all keys are generated from the project's own installed sources.
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.`;
@@ -14,13 +16,19 @@ async function runFontAwesomeCli(args, io = {}) {
14
16
  const stdout = io.stdout ?? console.log;
15
17
  const stderr = io.stderr ?? console.error;
16
18
  try {
19
+ const removed = ["--allow-pro", "--source-root", "--pro-mode"].find(
20
+ (flag) => args.some((arg) => arg === flag || arg.startsWith(`${flag}=`))
21
+ );
22
+ if (removed) {
23
+ throw new Error(
24
+ `${removed} was removed in 0.16.0. Pro keys follow the manifest; Pro sources always live in ${fontAwesomeProSourcesDir}/ and are used wherever it is installed.`
25
+ );
26
+ }
17
27
  const { values } = parseArgs({
18
28
  args: [...args],
19
29
  options: {
20
30
  manifest: { type: "string" },
21
31
  root: { type: "string" },
22
- "source-root": { type: "string" },
23
- "allow-pro": { type: "boolean" },
24
32
  out: { type: "string" },
25
33
  "virtual-types": { type: "string" },
26
34
  help: { type: "boolean", short: "h" }
@@ -38,44 +46,21 @@ async function runFontAwesomeCli(args, io = {}) {
38
46
  );
39
47
  }
40
48
  const root = resolve(io.cwd ?? process.cwd(), values.root ?? ".");
41
- const manifest = JSON.parse(
42
- await readFile(resolve(root, values.manifest), "utf8")
49
+ const manifest = await readFontAwesomeManifest(
50
+ resolve(root, values.manifest)
43
51
  );
44
- if (!manifest || typeof manifest !== "object" || Array.isArray(manifest)) {
45
- throw new Error("Font Awesome manifest must be a JSON object");
46
- }
47
- const record = manifest;
48
- const common = {
52
+ const selection = selectFontAwesomeManifestKeys(manifest, root);
53
+ const result = await generateFaIcons({
49
54
  root,
50
- sourceRoot: values["source-root"],
51
- allowPro: values["allow-pro"],
55
+ keys: selection.keys,
56
+ sourceRoot: selection.sourceRoot,
57
+ allowPro: selection.allowPro,
52
58
  outFile: values.out,
53
59
  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"]
69
60
  });
70
- if (installCommand) {
71
- stdout(
72
- `Install selected Font Awesome source packages with:
73
- ${installCommand}`
74
- );
75
- }
76
- const result = await generateFaIcons({ ...common, keys });
77
61
  stdout(
78
- `Prepared ${result.provenance.length} selected Font Awesome icon(s). Preserve generated license notices in application distribution.`
62
+ values.out ? `Prepared ${summarizeFaIcons(result.provenance)}
63
+ Preserve generated license notices in application distribution.` : `Prepared declarations for ${result.provenance.length} Font Awesome icon(s).`
79
64
  );
80
65
  return 0;
81
66
  } catch (error) {
@@ -25,6 +25,13 @@ export interface GeneratedFaIcons {
25
25
  provenance: readonly FontAwesomeProvenance[];
26
26
  dependencies: readonly string[];
27
27
  }
28
+ /**
29
+ * Summarizes generated icons and the source packages they came from, for an
30
+ * informational message after generation. Aliased packages show their
31
+ * canonical registry package.
32
+ * @internal
33
+ */
34
+ export declare function summarizeFaIcons(provenance: readonly FontAwesomeProvenance[]): string;
28
35
  /**
29
36
  * Generates descriptors for the requested catalog keys.
30
37
  *
@@ -0,0 +1,50 @@
1
+ /** Parsed manifest key groups; a missing `pro` group is empty. */
2
+ export interface FontAwesomeKeysManifest {
3
+ free: string[];
4
+ pro: string[];
5
+ }
6
+ /**
7
+ * Validates parsed manifest JSON.
8
+ *
9
+ * @throws If the value is not an object with a `free` key array and an
10
+ * optional `pro` key array.
11
+ */
12
+ export declare function parseFontAwesomeManifest(manifest: unknown): FontAwesomeKeysManifest;
13
+ /** Reads and validates a manifest file at an absolute or cwd-relative path. */
14
+ export declare function readFontAwesomeManifest(path: string): Promise<FontAwesomeKeysManifest>;
15
+ /**
16
+ * The isolated Pro source project every application uses, relative to the
17
+ * application root. Its presence selects the isolated layout.
18
+ */
19
+ export declare const fontAwesomeProSourcesDir = "fontawesome-pro-sources";
20
+ /**
21
+ * Reports whether the application at `root` uses the isolated layout, that
22
+ * is, whether `fontawesome-pro-sources/package.json` exists.
23
+ */
24
+ export declare function isFontAwesomeIsolated(root: string): boolean;
25
+ /**
26
+ * Reports whether the isolated source project at `root` is installed, that
27
+ * is, whether `fontawesome-pro-sources/node_modules` exists. Installing it
28
+ * with the token is what enables Pro icons in a build.
29
+ */
30
+ export declare function isFontAwesomeProInstalled(root: string): boolean;
31
+ /** Keys, Pro opt-in, and source root for one generation run. */
32
+ export interface FontAwesomeManifestSelection {
33
+ keys: string[];
34
+ allowPro: boolean;
35
+ sourceRoot?: string;
36
+ }
37
+ /** Returns the manifest's keys after rejecting Pro-tier keys under `free`. */
38
+ export declare function fontAwesomeManifestKeys(manifest: FontAwesomeKeysManifest): string[];
39
+ /**
40
+ * Selects the manifest keys for one build of the application at `root`.
41
+ *
42
+ * In the isolated layout, the `pro` keys are selected, and resolved from
43
+ * `fontawesome-pro-sources`, only when that project is installed; otherwise
44
+ * the build is Free-only and never reads it. Without the isolated project,
45
+ * the application installed its own sources, so every key is selected; a
46
+ * Free-only manifest has no `pro` keys.
47
+ *
48
+ * @throws If a Pro-tier key is listed under `free`.
49
+ */
50
+ export declare function selectFontAwesomeManifestKeys(manifest: FontAwesomeKeysManifest, root: string): FontAwesomeManifestSelection;