@featherk/icons 0.15.8 → 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 (32) hide show
  1. package/README.md +15 -3
  2. package/dist/docs-manifest.d.ts +1 -0
  3. package/dist/docs-manifest.js +7 -5
  4. package/dist/fontawesome/build.cjs +1 -2
  5. package/dist/fontawesome/build.d.ts +1 -1
  6. package/dist/fontawesome/build.mjs +2 -3
  7. package/dist/fontawesome/catalog.cjs +0 -13
  8. package/dist/fontawesome/catalog.d.ts +0 -8
  9. package/dist/fontawesome/catalog.mjs +0 -13
  10. package/dist/fontawesome/chunks/{generate-BBurrhLv.cjs → generate-B_FxftR7.cjs} +12 -1
  11. package/dist/fontawesome/chunks/{generate-Zq9q2YZD.mjs → generate-DF9R65sV.mjs} +13 -2
  12. package/dist/fontawesome/chunks/manifest-CSRIDvaR.mjs +56 -0
  13. package/dist/fontawesome/chunks/manifest-Yjw62jxG.cjs +55 -0
  14. package/dist/fontawesome/cli.cjs +23 -26
  15. package/dist/fontawesome/cli.mjs +23 -26
  16. package/dist/fontawesome/generate.d.ts +7 -0
  17. package/dist/fontawesome/manifest.d.ts +36 -0
  18. package/dist/fontawesome/setup.cjs +185 -180
  19. package/dist/fontawesome/setup.d.ts +2 -2
  20. package/dist/fontawesome/setup.mjs +186 -181
  21. package/dist/fontawesome/vite.cjs +64 -28
  22. package/dist/fontawesome/vite.d.ts +26 -5
  23. package/dist/fontawesome/vite.mjs +65 -29
  24. package/docs/ICONS.md +1 -1
  25. package/docs/fontawesome/CreateFontAwesomeManifest.md +1 -1
  26. package/docs/fontawesome/FontAwesome.md +48 -44
  27. package/docs/fontawesome/FontAwesomeCLI.md +14 -19
  28. package/docs/fontawesome/FontAwesomeDeveloperSetup.md +134 -0
  29. package/docs/fontawesome/LICENSING.md +107 -66
  30. package/package.json +1 -1
  31. package/dist/fontawesome/chunks/manifest-BB3q10t1.mjs +0 -20
  32. package/dist/fontawesome/chunks/manifest-C15Xa22L.cjs +0 -19
@@ -1,13 +1,34 @@
1
1
  import type { Plugin } from "vite";
2
- import type { FontAwesomeOptions } from "./types";
3
- /** Configuration for the Font Awesome virtual module plugin. */
4
- export interface FontAwesomeViteOptions extends FontAwesomeOptions {
2
+ /**
3
+ * Configuration for the Font Awesome virtual module plugin. Selections come
4
+ * from the same keys-only `{ free, pro }` manifest used by
5
+ * `featherk-fontawesome-setup`.
6
+ *
7
+ * When the project has a `fontawesome-pro-sources/` source project (the
8
+ * default setup), the manifest's `pro` keys are generated from it only in
9
+ * builds where that project is installed. Otherwise every key comes from the
10
+ * project's own installed packages.
11
+ */
12
+ export interface FontAwesomeViteOptions {
13
+ /** Keys-only manifest path, relative to the project root. */
14
+ manifest: string;
15
+ /** Project root, relative to Vite's root. */
16
+ root?: string;
5
17
  virtualTypesFile?: string | false;
18
+ /** Removed in 0.16.0; list keys in the manifest instead. */
19
+ keys?: never;
20
+ /** Removed in 0.16.0; Pro selection follows the manifest and layout. */
21
+ allowPro?: never;
22
+ /** Removed in 0.16.0; Pro sources always live in `fontawesome-pro-sources/`. */
23
+ sourceRoot?: never;
6
24
  }
7
25
  /**
8
26
  * Creates the Vite plugin for `virtual:featherk/fontawesome`.
9
27
  *
10
- * Catalog keys are resolved during Vite config setup, and their license
11
- * notices are emitted into production builds.
28
+ * Keys are read from the manifest and resolved during Vite config setup, and
29
+ * their license notices are emitted into production builds. Mode gating
30
+ * selects which keys to generate; it is not license authorization.
31
+ *
32
+ * @throws If `manifest` is missing or a removed option is provided.
12
33
  */
13
34
  export declare function featherkFontAwesome(options: FontAwesomeViteOptions): Plugin;
@@ -1,7 +1,7 @@
1
- import { resolve } from "node:path";
1
+ import { resolve, relative } from "node:path";
2
2
  import { realpath } from "node:fs/promises";
3
- import { getFontAwesomeInstallCommand } from "./catalog.mjs";
4
- import { g as generateFaIcons } from "./chunks/generate-Zq9q2YZD.mjs";
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
5
  const virtualId = "virtual:featherk/fontawesome";
6
6
  const resolvedId = `\0${virtualId}`;
7
7
  function dependencyKey(file) {
@@ -9,20 +9,56 @@ function dependencyKey(file) {
9
9
  return process.platform === "win32" ? path.toLowerCase() : path;
10
10
  }
11
11
  function featherkFontAwesome(options) {
12
+ const legacy = options;
13
+ if (legacy.keys !== void 0 || legacy.allowPro !== void 0) {
14
+ throw new Error(
15
+ 'Font Awesome Vite options "keys" and "allowPro" were removed in 0.16.0. List the keys in a { free, pro } manifest and pass { manifest: "fontawesome.keys.json" }.'
16
+ );
17
+ }
18
+ if (legacy.sourceRoot !== void 0 || legacy.proMode !== void 0) {
19
+ throw new Error(
20
+ `Font Awesome Vite options "sourceRoot" and "proMode" were removed in 0.16.0. Pro sources always live in ${fontAwesomeProSourcesDir}/ and are used wherever it is installed; pass only { manifest }.`
21
+ );
22
+ }
23
+ if (typeof options.manifest !== "string" || !options.manifest.trim()) {
24
+ throw new Error(
25
+ 'Font Awesome Vite options require a manifest path, such as { manifest: "fontawesome.keys.json" }'
26
+ );
27
+ }
12
28
  let root = resolve(options.root ?? process.cwd());
29
+ let logger;
13
30
  let generation;
14
31
  let dependencies = /* @__PURE__ */ new Set();
15
- function regenerate() {
16
- generation = generateFaIcons({
17
- keys: options.keys,
18
- root,
19
- sourceRoot: options.sourceRoot,
20
- allowPro: options.allowPro,
21
- virtualTypesFile: options.virtualTypesFile === false ? void 0 : options.virtualTypesFile ?? "src/featherk-fontawesome.d.ts"
22
- }).then((result) => {
23
- dependencies = new Set(result.dependencies.map(dependencyKey));
32
+ let watchFiles = [];
33
+ async function resolveSelection() {
34
+ const manifestFile = resolve(root, options.manifest);
35
+ const manifest = await readFontAwesomeManifest(manifestFile).catch(
36
+ (error) => {
37
+ throw new Error(
38
+ `Cannot read Font Awesome manifest ${relative(root, manifestFile) || manifestFile}: ${error instanceof Error ? error.message : String(error)}`
39
+ );
40
+ }
41
+ );
42
+ return {
43
+ ...selectFontAwesomeManifestKeys(manifest, root),
44
+ // Match the real paths that handleHotUpdate compares against.
45
+ manifestFile: await realpath(manifestFile)
46
+ };
47
+ }
48
+ function regenerate(selection) {
49
+ generation = (async () => {
50
+ const selected = selection ?? await resolveSelection();
51
+ const result = await generateFaIcons({
52
+ keys: selected.keys,
53
+ root,
54
+ sourceRoot: selected.sourceRoot,
55
+ allowPro: selected.allowPro,
56
+ virtualTypesFile: options.virtualTypesFile === false ? void 0 : options.virtualTypesFile ?? "src/featherk-fontawesome.d.ts"
57
+ });
58
+ watchFiles = [...result.dependencies, selected.manifestFile];
59
+ dependencies = new Set(watchFiles.map(dependencyKey));
24
60
  return result;
25
- });
61
+ })();
26
62
  return generation;
27
63
  }
28
64
  return {
@@ -30,20 +66,12 @@ function featherkFontAwesome(options) {
30
66
  enforce: "pre",
31
67
  async configResolved(config) {
32
68
  root = resolve(config.root, options.root ?? ".");
33
- const installCommand = options.keys === void 0 ? void 0 : getFontAwesomeInstallCommand(options.keys, {
34
- allowPro: options.allowPro
35
- });
36
- if (installCommand) {
37
- console.info(
38
- `[featherk-fontawesome] Install selected source packages with:
39
- ${installCommand}`
40
- );
41
- }
42
- await regenerate();
69
+ if (config.command === "build") logger = config.logger;
70
+ await regenerate(await resolveSelection());
43
71
  },
44
72
  async buildStart() {
45
- const result = await regenerate();
46
- for (const file of result.dependencies) this.addWatchFile(file);
73
+ await regenerate();
74
+ for (const file of watchFiles) this.addWatchFile(file);
47
75
  },
48
76
  resolveId(id) {
49
77
  return id === virtualId ? resolvedId : void 0;
@@ -53,14 +81,14 @@ ${installCommand}`
53
81
  return (await (generation ?? regenerate())).moduleCode;
54
82
  },
55
83
  async configureServer(server) {
56
- const result = await (generation ?? regenerate());
57
- server.watcher.add(result.dependencies);
84
+ await (generation ?? regenerate());
85
+ server.watcher.add(watchFiles);
58
86
  },
59
87
  async handleHotUpdate(context) {
60
88
  const file = await realpath(context.file).catch(() => context.file);
61
89
  if (!dependencies.has(dependencyKey(file))) return void 0;
62
- const result = await regenerate();
63
- context.server.watcher.add(result.dependencies);
90
+ await regenerate();
91
+ context.server.watcher.add(watchFiles);
64
92
  const module = context.server.moduleGraph.getModuleById(resolvedId);
65
93
  if (module) context.server.moduleGraph.invalidateModule(module);
66
94
  context.server.ws.send({ type: "full-reload" });
@@ -75,6 +103,14 @@ ${installCommand}`
75
103
  source: result.notices
76
104
  });
77
105
  }
106
+ },
107
+ async closeBundle() {
108
+ const result = await generation?.catch(() => void 0);
109
+ if (logger && result) {
110
+ logger.info(
111
+ `[featherk-fontawesome] Generated ${summarizeFaIcons(result.provenance)}`
112
+ );
113
+ }
78
114
  }
79
115
  };
80
116
  }
package/docs/ICONS.md CHANGED
@@ -211,4 +211,4 @@
211
211
  |rating_star_selected|switch_left|switch_off|switch_on|switch_right| |
212
212
  <!-- markdownlint-enable MD033-->
213
213
 
214
- > Generated: 2026-10-15T15:30:54.353Z
214
+ > Generated: 2026-10-15T21:01:16.022Z
@@ -79,7 +79,7 @@ The FeatherK catalog holds the complete metadata record. A consuming app lists o
79
79
  }
80
80
  ```
81
81
 
82
- For an optional Pro build, put its requested catalog keys in `pro`. Vite/CLI include those keys only when the app explicitly enables its authorized Pro profile. In this repository the shared key file is `demos/fontawesome.keys.json`.
82
+ Put Pro catalog keys in `pro`; a Pro key listed under `free` is rejected. The setup command installs Pro keys into the private `fontawesome-pro-sources/` project, and Vite and the CLI generate them wherever that project is installed (see [Quick Start](FontAwesome.md#quick-start)). In this repository the shared key file is `demos/fontawesome.keys.json`.
83
83
 
84
84
  ## Naming and Uniqueness Rules
85
85
 
@@ -6,21 +6,35 @@ The FeatherK UX/Design Engineer maintains the published catalog; the UX Team des
6
6
 
7
7
  ## Quick Start
8
8
 
9
- 1. UX designates the needed exact icon variant; the FeatherK UX/Design Engineer maintains its globally unique key and exact metadata in the published catalog. The license owner confirms Pro entitlement and approved release coverage.
10
- 2. Dev installs `@featherk/icons` with the Font Awesome Vite entry point and ensures compatible Vite 7.x or 8.x is available using [Install the Vite Integration](#install-the-vite-integration).
11
- 3. Dev checks the source mapping for selected keys, confirms access and availability, configures authorized registry access when required, then installs only the matching pinned npm packages using [Install Source Packages](#install-source-packages). For Pro, follow [Pro token setup](LICENSING.md#dev-setup-quick-start) before installation.
12
- 4. Dev configures the Vite plugin with only the selected keys. Pro keys require explicit Pro-profile opt-in and authorized installed sources; see [Vite Setup](#vite-setup).
13
- 5. Dev renders the selected descriptors through the virtual module using the [rendering example](#render-the-selected-key).
14
- 6. Dev preserves emitted license notices in application distribution as described in [Preserve license notices](#preserve-license-notices).
9
+ One keys-only manifest drives everything: the setup command installs exactly what it lists, and the Vite plugin generates exactly what it lists. For the full local and CI walkthrough, including TeamCity, see [FeatherK FontAwesome Developer Setup](FontAwesomeDeveloperSetup.md).
15
10
 
16
- Consumers need only the keys, not the other catalog records. These examples use keys present in the published catalog; verify source availability and license coverage for the project's exact selections. Install a FeatherK release/build containing these entry points; a prior published release does not gain them automatically. For CLI generation, including declaration preparation before an early type check, see [CLI and non-Vite setup](FontAwesomeCLI.md).
11
+ 1. **Create the manifest.** Put the UX-provided catalog keys in `fontawesome.keys.json` at the application root (see [Choose Font Awesome Icons and Create a Manifest](CreateFontAwesomeManifest.md)). Pro keys go under `pro`, and the license owner confirms Pro entitlement first.
17
12
 
18
- ```json
19
- {
20
- "free": ["user"],
21
- "pro": []
22
- }
23
- ```
13
+ ```json
14
+ {
15
+ "free": ["user"],
16
+ "pro": []
17
+ }
18
+ ```
19
+
20
+ 2. **Install the packages.** From the application root, [install `@featherk/icons` and Vite](#install-the-vite-integration), then run the setup command with the same manifest. It pins Free packages into the application and Pro packages into a private `fontawesome-pro-sources/` project, at their exact catalog versions; with Pro keys, it prompts for the package token. Commit `fontawesome-pro-sources/` with the application. See [Pro licensing and setup](LICENSING.md#default-isolated-pro-sources).
21
+
22
+ ```sh
23
+ npx featherk-fontawesome-setup --manifest fontawesome.keys.json
24
+ # No Pro keys? Add --free-only: public npm only, no token.
25
+ ```
26
+
27
+ 3. **Add the plugin** to `vite.config.ts` with the same manifest:
28
+
29
+ ```ts
30
+ featherkFontAwesome({ manifest: "fontawesome.keys.json" });
31
+ ```
32
+
33
+ 4. **Build** with the application's normal `dev` and `build` scripts. Wherever `fontawesome-pro-sources/` is installed (step 2 locally, or the token-scoped install step in CI), builds include the Pro icons. Where it isn't installed, builds include only the Free icons.
34
+ 5. **Render icons** from the virtual module; see the [rendering example](#render-the-selected-key).
35
+ 6. **Preserve license notices** in application distribution; see [Preserve license notices](#preserve-license-notices).
36
+
37
+ That is the whole recommended setup for Free-only and Free and Pro applications alike. Because Pro packages live in `fontawesome-pro-sources/`, the application's own install never needs the token. Type checks that run before Vite and projects that don't use Vite are covered under [Advanced setups](#advanced-setups).
24
38
 
25
39
  ### Pro Demo Example
26
40
 
@@ -80,51 +94,29 @@ npm install --save-dev @featherk/icons vite@^7.0.0
80
94
 
81
95
  ## Install Source Packages
82
96
 
83
- The catalog maps each key to its local dependency name, canonical registry package, export, and exact version. Dev installs only packages needed by selected keys, pinned to those exact versions. When Vite processes the selected keys, it prints one deduplicated `npm install --save-dev --save-exact ...` command in the terminal, including version aliases where needed. The CLI prints the same suggestion before generation. Run it from the consuming project with the appropriate registry access; FeatherK tooling never installs packages or handles credentials. During generation, the installed package's declared name is checked against `registryPackage` and its version against the catalog before the icon module is loaded. The Free example uses `@fortawesome/free-solid-svg-icons@7.0.0`; the Pro example needs authorized access to `@fortawesome/pro-light-svg-icons@7.0.0`.
84
-
85
- ```sh
86
- # Free source for the selected `user` key.
87
- npm install --save-dev --save-exact @fortawesome/free-solid-svg-icons@7.0.0
88
-
89
- # Pro package used by the example manifest.
90
- npm install --save-dev --save-exact @fortawesome/pro-light-svg-icons@7.0.0
91
- ```
92
-
93
- Aliases let one project install multiple versions of the same npm package under distinct dependency names. The catalog's `package` mapping specifies the dependency name for each selected version. See [alias details](#about-aliases-and-why-use-them).
94
-
95
- Never put a Pro token in the command or commit it. See [Pro licensing and setup](LICENSING.md) for secure registry configuration.
97
+ Run `featherk-fontawesome-setup --manifest fontawesome.keys.json` from the application root (Quick Start step 2). The catalog maps each key to its local dependency name, canonical registry package, export, and exact version, and the command installs only the packages the manifest needs, pinned to those versions, including npm aliases where one release must sit beside another (see [alias details](#about-aliases-and-why-use-them)). Free packages go into the application's `devDependencies`. Pro packages go into `fontawesome-pro-sources/`, whose `.npmrc` holds only a token placeholder, and the token is passed only to npm. On a fresh clone or in CI, run `npx featherk-fontawesome-setup` without arguments after the application's `npm ci` to install that project from its lockfile. See [Pro licensing and setup](LICENSING.md#consuming-applications) for the token, CI, TeamCity, and the `--pro-in-app` exception. Never put a Pro token in a command or commit it.
96
98
 
97
- The printed command is an install suggestion, not a license or access check. Pro builds still require separately configured authorized registry access and the explicit Pro profile. Vite may print the same selected-package command on each startup; it includes only packages mapped from that app's selected keys.
99
+ During generation, the installed package's declared name is checked against `registryPackage` and its version against the catalog before the icon module is loaded. When a package is missing, generation fails with a message that points to the setup command; nobody installs Font Awesome packages by hand. At the end of each build, Vite logs the source packages the icons came from, for information only. The setup command is not a license or access check.
98
100
 
99
101
  ## Vite Setup
100
102
 
101
- The following setup is Dev-owned and assumes the app keys-only manifest and required license approvals are in place.
103
+ Point the plugin at the manifest that `featherk-fontawesome-setup` installed from:
102
104
 
103
105
  ```ts
104
106
  import { defineConfig } from "vite";
105
107
  import vue from "@vitejs/plugin-vue";
106
108
  import { featherkFontAwesome } from "@featherk/icons/fontawesome/vite";
107
- import manifest from "./fontawesome.keys.json";
108
109
 
109
- const proEnabled = process.env.FEATHERK_FONTAWESOME_PRO === "1";
110
-
111
- // Step 1: Use UX-provided keys; verify any required Pro entitlement separately.
112
- // Step 2: Ensure @featherk/icons and Vite 7 or 8 are available.
113
- // Step 3: Install source packages mapped by the selected catalog keys before Vite starts.
114
110
  export default defineConfig({
115
- // Step 4: Pro keys are included only for the explicitly enabled profile.
116
- plugins: [
117
- vue(),
118
- featherkFontAwesome({
119
- keys: [...manifest.free, ...(proEnabled ? manifest.pro : [])],
120
- allowPro: proEnabled,
121
- sourceRoot: proEnabled ? "pro" : undefined,
122
- }),
123
- ],
111
+ plugins: [vue(), featherkFontAwesome({ manifest: "fontawesome.keys.json" })],
124
112
  });
125
113
  ```
126
114
 
127
- Enable JSON imports in the consumer's TypeScript configuration if necessary. The app passes only keys; the catalog supplies exact metadata, and the generator validates installed source versions and identities at runtime.
115
+ The plugin reads the manifest relative to the Vite project root and validates every key through the catalog. It always generates the `free` keys. When the project has `fontawesome-pro-sources/`, it adds the `pro` keys, resolved from that project, only when that project is installed (its `node_modules` exists); otherwise it never reads it. A build where the install was skipped is Free-only, and code that uses a Pro key then fails type checking, because the generated key union contains only Free keys. An application set up with `--pro-in-app` has no such directory, so every build includes its `pro` keys from the application's own packages. A Pro-tier key listed under `free` is rejected with a message to move it to `pro`. Selecting keys this way is not license authorization. The plugin watches the manifest and reloads the dev server when it changes. The catalog supplies exact metadata, and the generator validates installed source versions and identities at runtime.
116
+
117
+ ### Upgrading from 0.15
118
+
119
+ 0.16.0 removed the plugin's `keys`, `allowPro`, and `sourceRoot` options; the setup command's `--keys`, `--source-root`, `--init`, `--force`, and `--refresh-lock`; and the CLI's `--allow-pro` and `--source-root`. Passing them fails with a message that explains the replacement. Move the keys into the manifest, pass `{ manifest }`, and rerun `featherk-fontawesome-setup --manifest fontawesome.keys.json`, which moves Pro packages into `fontawesome-pro-sources/`. An application that installed Pro into its own dependencies keeps that layout with `--pro-in-app`.
128
120
 
129
121
  ### Render the Selected Key
130
122
 
@@ -217,6 +209,18 @@ Keep this file covered by the project's TypeScript `include` patterns, such as `
217
209
 
218
210
  In the FeatherK monorepo, the exact root-relative pattern is `demos/src/featherk-fontawesome.d.ts`. ESLint's global ignores, `.prettierignore`, and `.gitignore` exclude that file; the demo TypeScript configuration still includes it. The generator, plugin, and handwritten declarations remain linted. If a type checker runs before Vite starts, see [CLI and non-Vite setup](FontAwesomeCLI.md) for declaration preparation. The library does not modify consumer lint configuration or inject ESLint-disable directives.
219
211
 
212
+ ## Advanced Setups
213
+
214
+ Most applications need only the [Quick Start](#quick-start). Use these only when it doesn't fit.
215
+
216
+ ### Pro in the Application
217
+
218
+ An application whose tooling cannot use the separate `fontawesome-pro-sources/` project can install Pro packages into its own dependencies with `featherk-fontawesome-setup --manifest fontawesome.keys.json --pro-in-app` (see [Exception: Pro in the Application](LICENSING.md#exception-pro-in-the-application)). The plugin options stay `{ manifest }`, and every build includes the Pro keys. The cost is that every install of the application, by every developer and CI job, then needs the token. Use it only with a real reason.
219
+
220
+ ### Type Checks Before Vite, and Non-Vite Projects
221
+
222
+ The plugin writes its declarations when Vite starts, which is too late for a `vue-tsc` or `tsc` step that runs first. Projects in that situation, and projects that don't use Vite, generate with the `featherk-fontawesome` CLI from the same manifest; see [CLI and non-Vite setup](FontAwesomeCLI.md). Custom Node tooling can call `generateFaIcons` from `@featherk/icons/fontawesome/build`, which takes resolved keys instead of a manifest.
223
+
220
224
  ## Supported Sources and Licensing
221
225
 
222
226
  ### Verified Free Consumer
@@ -1,41 +1,38 @@
1
1
  # Font Awesome CLI and Non-Vite Setup
2
2
 
3
- This Dev-owned supplement assumes UX/Design has supplied catalog keys. The catalog contains the source metadata; the app manifest contains only keys the project uses. For icon choice and key assignment, start with [Choose Font Awesome Icons and Create a Manifest](CreateFontAwesomeManifest.md). For the default Vite integration, see [Font Awesome Build Integration](FontAwesome.md).
3
+ This is an advanced supplement. Most applications need only the Vite plugin; start with the [Quick Start](FontAwesome.md#quick-start). Use the `featherk-fontawesome` CLI when a type checker runs before Vite, or when the project doesn't use Vite.
4
4
 
5
- ## Quick Start
5
+ The CLI reads the same keys-only manifest as the setup command and the Vite plugin, and selects keys the same way:
6
6
 
7
- 1. Receive the UX-provided catalog keys and required license approvals.
8
- 2. Dev installs `@featherk/icons` at a release containing the CLI or Node API; for example, `npm install --save-dev @featherk/icons`.
9
- 3. Dev installs only the packages mapped to selected keys in the published catalog, pinned to exact versions. For Pro, follow [Pro token setup](LICENSING.md#dev-setup-quick-start) before installation; package examples are in [Install Source Packages](FontAwesome.md#install-source-packages).
10
- 4. Dev generates virtual-module declarations or a regular ESM module from the keys-only manifest.
11
- 5. Dev imports the generated module where needed, type-checks declarations, and preserves emitted license notices.
7
+ - When the project has `fontawesome-pro-sources/` (the [default setup](LICENSING.md#default-isolated-pro-sources)), it generates the `pro` keys from that project only when it is installed. Otherwise it generates the `free` keys alone.
8
+ - Without `fontawesome-pro-sources/` (Free-only or `--pro-in-app` setups), it generates every manifest key from the application's installed packages.
12
9
 
13
- The CLI prints one deduplicated exact install command for the packages mapped to selected keys before generation. Run that command yourself from the consumer project after configuring any required registry access. The CLI validates installed Font Awesome source packages; it does not install them or authenticate with a registry. A prior FeatherK release does not gain the CLI or Node API entry points automatically.
10
+ Install source packages first with `featherk-fontawesome-setup --manifest fontawesome.keys.json` ([Install Source Packages](FontAwesome.md#install-source-packages)). The CLI validates the installed packages; it does not install them or authenticate with a registry.
14
11
 
15
- ### Generate declarations before a Vite type check
12
+ ## Generate Declarations Before a Vite Type Check
16
13
 
17
14
  The Vite plugin writes `src/featherk-fontawesome.d.ts` on startup by default. If `vue-tsc` or `tsc` runs before Vite starts, prepare that file first:
18
15
 
19
16
  ```sh
20
- # Step 4: Generate the virtual-module declarations before standalone type checking.
17
+ # Generate the virtual-module declarations before standalone type checking.
21
18
  npm exec -- featherk-fontawesome --manifest fontawesome.keys.json --virtual-types src/featherk-fontawesome.d.ts
22
19
  ```
23
20
 
24
- The manifest uses `{ "free": ["key"], "pro": ["key"] }`. By default, the CLI selects only `free` keys. For a licensed profile, add `--allow-pro`; the CLI then includes the `pro` keys and rejects Pro selections if the exact source package cannot be resolved. Configure the Vite plugin with the same key file and profile. `virtualTypesFile` can select another project-local `.d.ts` path or disable plugin writing with `false`.
21
+ The CLI and the Vite plugin check the same installed `fontawesome-pro-sources/`, so a declaration step that runs just before the build selects the same keys. The plugin's `virtualTypesFile` option can select another project-local `.d.ts` path or disable plugin writing with `false`.
25
22
 
26
- ### Generate a module for a non-Vite application
23
+ ## Generate a Module for a Non-Vite Application
27
24
 
28
25
  No migration to Vite is required. Generate a regular ESM module and adjacent declarations/notices:
29
26
 
30
27
  ```sh
31
- # Step 4: Generate application-local ESM output from the selected manifest.
28
+ # Generate application-local ESM output from the manifest.
32
29
  npm exec -- featherk-fontawesome --manifest fontawesome.keys.json --out src/generated/fontawesome/icons.mjs
33
30
  ```
34
31
 
35
32
  Import the generated module before running the existing application build:
36
33
 
37
34
  ```js
38
- // Step 5: Use the manifest key selected for this application.
35
+ // Use a manifest key selected for this application.
39
36
  import { getFaIcon } from "./generated/fontawesome/icons.mjs";
40
37
 
41
38
  const userIcon = getFaIcon("user");
@@ -45,15 +42,13 @@ Run generation again when selections change, including before local development.
45
42
 
46
43
  ## Node API and CLI Options
47
44
 
48
- `generateFaIcons` from `@featherk/icons/fontawesome/build` accepts selected `keys`, optional `allowPro`, `root`, `sourceRoot`, `outFile`, and `virtualTypesFile`. It returns ESM code, file-module declarations, ambient virtual-module declarations, notices, provenance, and source dependency paths. Without output options, it writes nothing. Catalog keys are the only supported selection input. Pro keys require `allowPro: true`, which is an accidental-use guard, not proof of license entitlement.
45
+ The CLI accepts `--manifest`, `--root`, `--out`, `--virtual-types`, and `--help`. The manifest contains a `free` array and an optional `pro` array of catalog keys; a Pro-tier key under `free` is rejected. `--allow-pro`, `--source-root`, and `--pro-mode` were removed in 0.16.0. Specify at least one output. Paths are relative to `--root` or the current directory. File output uses `.js`/`.mjs` with `.d.ts`/`.d.mts` declarations; ambient output uses `.d.ts` and must not overwrite the file-module declaration.
49
46
 
50
- The CLI accepts `--manifest`, `--root`, `--source-root`, `--allow-pro`, `--out`, `--virtual-types`, and `--help`. The manifest contains `free` and optional `pro` arrays of catalog keys; full-record `icons` manifests are rejected. To migrate from 0.14.0, replace each full selection record with its UX-provided catalog key and use the published catalog for source metadata. Specify at least one output. Paths are relative to `--root` or the current directory. File output uses `.js`/`.mjs` with `.d.ts`/`.d.mts` declarations; ambient output uses `.d.ts` and must not overwrite the file-module declaration.
47
+ For custom Node tooling, `generateFaIcons` from `@featherk/icons/fontawesome/build` takes already-resolved `keys`, optional `allowPro`, `root`, `sourceRoot`, `outFile`, and `virtualTypesFile`. It returns ESM code, file-module declarations, ambient virtual-module declarations, notices, provenance, and source dependency paths, and writes nothing without output options. Pro keys require `allowPro: true`, which is an accidental-use guard, not proof of license entitlement. Prefer the CLI, which derives these, including `sourceRoot: "fontawesome-pro-sources"`, from the manifest and layout.
51
48
 
52
49
  Output must remain inside the consumer project, outside `node_modules` and the `@featherk/icons` package. The independent runtime `createFontAwesomeService` is available from `@featherk/icons/fontawesome`; Node tooling is never imported through the custom-icon root service.
53
50
 
54
- The API and Vite plugin accept `sourceRoot` to resolve installed packages from a separate source project without moving the output boundary. The CLI equivalent is `--source-root`. Relative source paths resolve from `root`; authentication still happens during npm installation, never in the generator or browser.
55
-
56
- To install source packages, use the separate `featherk-fontawesome-setup` command described in [Consuming Applications](LICENSING.md#consuming-applications). It supports the standard Free and Pro app-root setup, Free-only setup, and the isolated source project. The generator does not install anything; the setup command is the only FeatherK tool that receives the package token.
51
+ A source root resolves installed packages from a separate source project without moving the output boundary. Relative source paths resolve from `root`; authentication still happens during npm installation, never in the generator or browser. The generator does not install anything; `featherk-fontawesome-setup` is the only FeatherK tool that receives the package token.
57
52
 
58
53
  ## Generated Output and Source Checks
59
54
 
@@ -0,0 +1,134 @@
1
+ # FeatherK FontAwesome Developer Setup
2
+
3
+ This is the step-by-step setup for a developer adding Font Awesome icons to an application with `@featherk/icons`, on a local machine and in CI. It covers the default layout every team uses: Free packages in the application, Pro packages in a private `fontawesome-pro-sources/` project. For background, see [Font Awesome Build Integration](FontAwesome.md). For licensing, token handling, and the `--free-only` and `--pro-in-app` exceptions, see [Font Awesome Pro Licensing and Setup](LICENSING.md).
4
+
5
+ ## Before You Start
6
+
7
+ - Confirm package access, release coverage, and Creator seats with the license owner. A package token enables downloads; it grants no license seats, and neither does `@featherk/icons`.
8
+ - Get a Pro Package Token from the [Font Awesome Tokens page](https://fontawesome.com/account/tokens). Never put the token in a file, a command, or shell history. The setup command reads it from `FONTAWESOME_PACKAGE_TOKEN` or asks for it at a hidden prompt.
9
+ - Get the catalog keys for the icons you need from UX; see [Choose Font Awesome Icons and Create a Manifest](CreateFontAwesomeManifest.md).
10
+ - Install `@featherk/icons` and the application's Vite major (7 or 8) as development dependencies, as described in [Install the Vite Integration](FontAwesome.md#install-the-vite-integration).
11
+
12
+ ## Local Machine
13
+
14
+ 1. **Create `fontawesome.keys.json`** at the application root. It is the only list of selected icons: the setup command installs exactly what it lists, and the Vite plugin generates exactly what it lists. Pro keys go under `pro`.
15
+
16
+ ```json
17
+ {
18
+ "free": ["user"],
19
+ "pro": ["pro-house-light"]
20
+ }
21
+ ```
22
+
23
+ 2. **Install the source packages** from the application root. Enter the token at the hidden prompt when asked:
24
+
25
+ ```sh
26
+ npx featherk-fontawesome-setup --manifest fontawesome.keys.json
27
+ ```
28
+
29
+ The command looks up each key's exact package and version in the published catalog, then:
30
+ - installs the Free packages into the application's `devDependencies` from public npm, without the token;
31
+ - writes the Pro pins into `fontawesome-pro-sources/` (a `package.json`, a `.gitignore`, and an `.npmrc` with only a token placeholder), then installs that project with the token.
32
+
33
+ You never install a Font Awesome package by hand.
34
+
35
+ 3. **Commit** `fontawesome.keys.json`, `package.json`, `package-lock.json`, and `fontawesome-pro-sources/`, including its `package-lock.json`. Its `node_modules` stays ignored. Never put a real token in any `.npmrc`.
36
+
37
+ 4. **Add the plugin** to `vite.config.ts`:
38
+
39
+ ```ts
40
+ import { featherkFontAwesome } from "@featherk/icons/fontawesome/vite";
41
+
42
+ export default defineConfig({
43
+ plugins: [
44
+ vue(),
45
+ featherkFontAwesome({ manifest: "fontawesome.keys.json" }),
46
+ ],
47
+ });
48
+ ```
49
+
50
+ 5. **Run the application's normal scripts**, such as `npm run dev` and `npm run build`, without the token. Because `fontawesome-pro-sources/` is installed, they include the Pro icons. At the end of each build, Vite lists the source packages the icons came from; the list is informational only.
51
+
52
+ 6. **Render icons** from the virtual module; see [Render the Selected Key](FontAwesome.md#render-the-selected-key).
53
+
54
+ ```ts
55
+ import { getFaIcon } from "virtual:featherk/fontawesome";
56
+
57
+ const houseIcon = getFaIcon("pro-house-light");
58
+ ```
59
+
60
+ If a type check such as `vue-tsc` runs before Vite, generate the declarations first with the same manifest:
61
+
62
+ ```sh
63
+ npx featherk-fontawesome --manifest fontawesome.keys.json --virtual-types src/featherk-fontawesome.d.ts
64
+ ```
65
+
66
+ ### Fresh Clone
67
+
68
+ After the application's normal `npm ci`, install the committed Pro sources from their lockfile with the token:
69
+
70
+ ```sh
71
+ npx featherk-fontawesome-setup
72
+ ```
73
+
74
+ Without this step, the application still installs and builds, with the Free icons only. Code that uses a Pro key then fails type checking, which shows that the step was skipped.
75
+
76
+ ### Changing Icons
77
+
78
+ Edit `fontawesome.keys.json`, rerun `npx featherk-fontawesome-setup --manifest fontawesome.keys.json`, and commit the result. The command updates both sets of pins; when the Pro pins change, it regenerates `fontawesome-pro-sources/package-lock.json`. Restart Vite after installing.
79
+
80
+ ## CI
81
+
82
+ A build that includes Pro icons has three steps. Only the middle one has the token:
83
+
84
+ 1. The application's normal `npm ci`, without the token.
85
+ 2. `npx featherk-fontawesome-setup`, with `FONTAWESOME_PACKAGE_TOKEN`. In CI it installs `fontawesome-pro-sources/` only from the committed lockfile and refuses `--manifest` setup.
86
+ 3. The application's normal build, test, and deploy steps, without the token.
87
+
88
+ A build that skips step 2 is Free-only. Never expose the token to untrusted pull-request builds.
89
+
90
+ ### TeamCity
91
+
92
+ 1. Add a build parameter named `fontawesome.package.token` with type **Password**. Do not use an `env.` prefix; TeamCity would export it to every step.
93
+ 2. Leave the existing `npm ci` step unchanged, and add a Command Line step after it that sets the token for one command:
94
+
95
+ ```sh
96
+ # Linux agent
97
+ FONTAWESOME_PACKAGE_TOKEN='%fontawesome.package.token%' npx featherk-fontawesome-setup
98
+ ```
99
+
100
+ ```bat
101
+ rem Windows agent
102
+ set "FONTAWESOME_PACKAGE_TOKEN=%fontawesome.package.token%"
103
+ npx featherk-fontawesome-setup
104
+ ```
105
+
106
+ 3. Leave the build and the authorized deploy steps unchanged. They never reference the parameter.
107
+
108
+ Build agents must be able to reach `npm.fontawesome.com`. For GitHub Actions and the full token-scoping rules, see [CI and Deployment](LICENSING.md#ci-and-deployment).
109
+
110
+ ### Build Caches
111
+
112
+ A build cache keyed on tracked files, such as Turborepo's, must also key on whether `fontawesome-pro-sources/` is installed, or it can replay a Free build where Pro is expected. Add the install marker to the build's inputs:
113
+
114
+ ```json
115
+ "inputs": ["$TURBO_DEFAULT$", "fontawesome-pro-sources/node_modules/.package-lock.json"]
116
+ ```
117
+
118
+ Keep builds that include Pro icons out of shared or remote caches.
119
+
120
+ ## Distribution
121
+
122
+ > [!WARNING]
123
+ > A Pro build contains Font Awesome SVG path data. Publish it only where access controls, license coverage, and the required seats are confirmed, and preserve `featherk-fontawesome.licenses.txt` in every application distribution.
124
+
125
+ ## Checklist
126
+
127
+ - [ ] License owner confirmed package access, release coverage, and seats
128
+ - [ ] `fontawesome.keys.json` lists UX-provided keys, with Pro keys under `pro`
129
+ - [ ] `npx featherk-fontawesome-setup --manifest fontawesome.keys.json` ran locally
130
+ - [ ] `fontawesome-pro-sources/` and both lockfiles are committed; no token is in any file
131
+ - [ ] `vite.config.ts` uses `featherkFontAwesome({ manifest: "fontawesome.keys.json" })`
132
+ - [ ] CI runs `npx featherk-fontawesome-setup` with the token, between `npm ci` and the build
133
+ - [ ] Any build cache keys on the `fontawesome-pro-sources` install marker
134
+ - [ ] `featherk-fontawesome.licenses.txt` ships with the application