@uxf/icons-generator 11.129.0 → 12.2.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.
package/README.md CHANGED
@@ -17,7 +17,7 @@ This is a build-time dev tool run via the `icons-gen` binary. The runtime `<Icon
17
17
  yarn add -D @uxf/icons-generator
18
18
  ```
19
19
 
20
- Requires Node `>= 24`. Peer dependency: `@uxf/core` (`11.114.0`). To use the Font Awesome Pro adapter, additionally install the per-style FA packages you reference (see [Providers](#providers--font-awesome-pro-adapter)).
20
+ Requires Node `>= 24`. Peer dependency: `@uxf/core` (`11.114.0`). The Font Awesome Pro adapter needs no extra packages — it streams icons from the kit at generation time, so it only needs the `@awesome.me` scope to resolve through your registry (see [Providers](#providers--font-awesome-pro-adapter)).
21
21
 
22
22
  ## Quick start
23
23
 
@@ -145,40 +145,45 @@ This augmentation is what makes `@uxf/ui/icon`'s `IconName` (`keyof IconsSet`) a
145
145
 
146
146
  ## Providers — Font Awesome Pro adapter
147
147
 
148
- The `faPro` adapter reads icon data from the per-style Font Awesome packages. Install only the styles you actually use.
149
-
150
- | Namespace | Package |
151
- | ------------------------- | ---------------------------------------------- |
152
- | `brands.*` | `@fortawesome/free-brands-svg-icons` |
153
- | `regular.*` | `@fortawesome/pro-regular-svg-icons` |
154
- | `solid.*` | `@fortawesome/pro-solid-svg-icons` |
155
- | `light.*` | `@fortawesome/pro-light-svg-icons` |
156
- | `thin.*` | `@fortawesome/pro-thin-svg-icons` |
157
- | `duotone.*` | `@fortawesome/pro-duotone-svg-icons` |
158
- | `duotone-regular.*` | `@fortawesome/duotone-regular-svg-icons` |
159
- | `duotone-light.*` | `@fortawesome/duotone-light-svg-icons` |
160
- | `duotone-thin.*` | `@fortawesome/duotone-thin-svg-icons` |
161
- | `sharp-regular.*` | `@fortawesome/sharp-regular-svg-icons` |
162
- | `sharp-solid.*` | `@fortawesome/sharp-solid-svg-icons` |
163
- | `sharp-light.*` | `@fortawesome/sharp-light-svg-icons` |
164
- | `sharp-thin.*` | `@fortawesome/sharp-thin-svg-icons` |
165
- | `sharp-duotone-regular.*` | `@fortawesome/sharp-duotone-regular-svg-icons` |
166
- | `sharp-duotone-solid.*` | `@fortawesome/sharp-duotone-solid-svg-icons` |
167
- | `sharp-duotone-light.*` | `@fortawesome/sharp-duotone-light-svg-icons` |
168
- | `sharp-duotone-thin.*` | `@fortawesome/sharp-duotone-thin-svg-icons` |
169
-
170
- An icon is referenced as `"<namespace>.<kebab-icon-name>"` (e.g. `"regular.calendar-check"`). The legacy `@fortawesome/fontawesome-pro` monolith is no longer supported — the adapter throws if it is installed, so uninstall it.
171
-
172
- ### Local development setup
148
+ The `faPro` adapter resolves icons from a Font Awesome **kit** package (`@awesome.me/kit-…`), the
149
+ only distribution channel that carries every style FA 7 offers. Nothing is installed: at generation
150
+ time the CLI streams the kit tarball, pulls out just the SVGs your config names, and discards the
151
+ rest. A ~110 MB archive therefore leaves behind a few kilobytes and never lands in `node_modules`
152
+ or a Docker image.
173
153
 
174
- ```bash
175
- # Set registry and token
176
- npm config set "@fortawesome:registry" https://npm.fontawesome.com/
177
- npm config set "//npm.fontawesome.com/:_authToken" YOUR_TOKEN
154
+ ### Resolution order
178
155
 
179
- # Install only the styles you use
180
- npm install --save-dev @fortawesome/pro-regular-svg-icons @fortawesome/free-brands-svg-icons
181
- ```
156
+ For each `"<namespace>.<icon-name>"` the adapter tries, in order:
157
+
158
+ 1. **An installed `@fortawesome/*-svg-icons` package** — deprecated, kept so existing projects keep
159
+ building. Using one prints a warning; support is removed in a future major.
160
+ 2. **The streamed kit package** — the supported path.
161
+ 3. **`<configDirectory>/icons-fallbacks/faPro.json`** — the snapshot written on every successful
162
+ resolve, so a project without Font Awesome access can still rebuild the icons it already has.
163
+
164
+ The monolithic `@fortawesome/fontawesome-pro` is no longer supported at all: the adapter throws if
165
+ it finds it installed.
166
+
167
+ ### Registry access
168
+
169
+ Kits live in the `@awesome.me` scope on Font Awesome's own registry, so that scope has to resolve
170
+ through our Verdaccio (which caches the tarballs, keeping FA bandwidth costs down). See
171
+ `docs/recipes/fontawesome-kit-verdaccio.md` for the server side, and
172
+ `docs/migration/fa-pro-kit-stream.md` for what a consuming project has to change.
173
+
174
+ Registry and credentials are read from the same `.npmrc` and `.yarnrc.yml` files your package
175
+ manager uses — npm-based and Yarn-based projects both work without extra configuration.
176
+
177
+ ### Namespaces
178
+
179
+ A namespace is the style directory inside the package, so `"regular.calendar-check"` resolves to
180
+ `regular/calendar-check.svg`. For the classic families it matches what the per-style packages used:
181
+ `brands`, `regular`, `solid`, `light`, `thin`, `duotone`, `duotone-regular`, `duotone-light`,
182
+ `duotone-thin`, and the `sharp-` and `sharp-duotone-` variants of each. Styles a kit adds on top
183
+ appear under their own directory name.
184
+
185
+ The exhaustive list is the generated `FaProIconName` union in `src/fa-pro-types.ts`, regenerated by
186
+ `npm run icon-types:gen` in this monorepo.
182
187
 
183
188
  ### Usage
184
189
 
@@ -196,11 +201,43 @@ module.exports = {
196
201
  };
197
202
  ```
198
203
 
199
- `faPro.adapter([...])` names each icon `faPro_<namespace>.<name>`, while `faPro.icon(...)` lets you assign a custom key.
204
+ `faPro.adapter([...])` names each icon `faPro_<namespace>.<name>`, while `faPro.icon(...)` lets you
205
+ assign a custom key. Both register the icon for the prefetch that runs before generation, so they
206
+ must be called while the config module is being loaded — which is what the examples above do.
207
+
208
+ ### Which kit version, and how it is upgraded
209
+
210
+ The kit **and its version** are pinned in `src/utils/_faProTarballCache.ts`, next to the generated
211
+ `FaProIconName` union they belong to. Both ship in this package, so a project gets a matched pair and
212
+ never has to configure a version: bumping `@uxf/icons-generator` is how you move to a newer kit.
213
+
214
+ That also means a warm run needs no registry access at all, and that a kit republished upstream
215
+ cannot change anybody's sprite behind their back.
216
+
217
+ Adopting a new kit version is one commit here:
218
+
219
+ ```bash
220
+ UXF_FA_PRO_VERSION=latest npx tsx packages/icons-generator/scripts/generate-fa-pro-types.ts # what is out there?
221
+ # set DEFAULT_VERSION in src/utils/_faProTarballCache.ts to that version
222
+ npm run icon-types:gen
223
+ ```
224
+
225
+ The generator refuses to write a union built from a version other than the pinned one, so the two
226
+ cannot drift.
227
+
228
+ ### Caching
200
229
 
201
- ### Without the private key
230
+ Fetched SVGs and the package's icon-name index are cached under
231
+ `~/.cache/uxf-icons-generator/fa-pro/v<schema>/<package>_<version>/` — the package and version are
232
+ slugified, so the real directory looks like `v2/_awesome.me_kit-0618a3d496_1.0.2`. A run that introduces no new icon
233
+ performs no network I/O. Point `UXF_FA_PRO_CACHE_ROOT` somewhere inside the build directory to let
234
+ CI cache it; a version bump simply misses the cache and refills it.
202
235
 
203
- If your project already has generated icons, the Font Awesome Pro packages are not required to rebuild them. On each successful resolve the adapter caches the icon into `<configDirectory>/icons-fallbacks/faPro.json`; when a package is missing, it reads from that fallback file instead. Existing icons keep working, but **adding new** provider icons still requires the corresponding FA package installed.
236
+ | Variable | Default | Purpose |
237
+ | ----------------------- | ------------------------------ | ----------------------------------------------------------------------------- |
238
+ | `UXF_FA_PRO_PACKAGE` | `@awesome.me/kit-0618a3d496` | Source package. Accepts any kit, or `@fortawesome/fontawesome-pro`. |
239
+ | `UXF_FA_PRO_VERSION` | the pinned `DEFAULT_VERSION` | Override the version. `latest` asks the registry — for discovery, not builds. |
240
+ | `UXF_FA_PRO_CACHE_ROOT` | `~/.cache/uxf-icons-generator` | Where cached SVGs and the index live. |
204
241
 
205
242
  ## Generated output
206
243
 
@@ -273,6 +310,10 @@ declare module "@uxf/ui/icon/theme" {
273
310
  - **Paths are `cwd`-relative and need slashes.** `configDirectory` and `generatedDirectory` are joined onto `process.cwd()`, so both must start and end with `/`.
274
311
  - **`typescript: false` currently has no effect.** The generator always emits `icons.ts` — the flag falls back to `true` internally.
275
312
  - **The `faPro` provider is a deep import:** `@uxf/icons-generator/src/providers/fa-pro` (the published files preserve the `src/` layout). The `IconsConfig` type is at `@uxf/icons-generator/src/types`.
313
+ - **Provider icons are resolved before generation, not lazily.** `faPro.icon(...)` and
314
+ `faPro.adapter([...])` register their names when the config module loads, and the CLI resolves
315
+ them all in one streamed pass. Building an icon name inside a callback that runs later than config
316
+ load will not be prefetched.
276
317
  - **Keep the default `moduleName`** (`@uxf/ui/icon/theme`) unless you intentionally augment a different module; changing it breaks the `@uxf/ui` `IconName` inference.
277
318
 
278
319
  ## Links
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uxf/icons-generator",
3
- "version": "11.129.0",
3
+ "version": "12.2.0",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -25,23 +25,6 @@
25
25
  "@uxf/core": "11.129.0"
26
26
  },
27
27
  "devDependencies": {
28
- "@fortawesome/duotone-light-svg-icons": "7.3.1",
29
- "@fortawesome/duotone-regular-svg-icons": "7.3.1",
30
- "@fortawesome/duotone-thin-svg-icons": "7.3.1",
31
- "@fortawesome/free-brands-svg-icons": "7.3.1",
32
- "@fortawesome/pro-duotone-svg-icons": "7.3.1",
33
- "@fortawesome/pro-light-svg-icons": "7.3.1",
34
- "@fortawesome/pro-regular-svg-icons": "7.3.1",
35
- "@fortawesome/pro-solid-svg-icons": "7.3.1",
36
- "@fortawesome/pro-thin-svg-icons": "7.3.1",
37
- "@fortawesome/sharp-duotone-light-svg-icons": "7.3.1",
38
- "@fortawesome/sharp-duotone-regular-svg-icons": "7.3.1",
39
- "@fortawesome/sharp-duotone-solid-svg-icons": "7.3.1",
40
- "@fortawesome/sharp-duotone-thin-svg-icons": "7.3.1",
41
- "@fortawesome/sharp-light-svg-icons": "7.3.1",
42
- "@fortawesome/sharp-regular-svg-icons": "7.3.1",
43
- "@fortawesome/sharp-solid-svg-icons": "7.3.1",
44
- "@fortawesome/sharp-thin-svg-icons": "7.3.1",
45
28
  "@types/node": "24",
46
29
  "@uxf/core": "11.129.0",
47
30
  "tsx": "4.23.12"
@@ -0,0 +1 @@
1
+ export {};
@@ -1,93 +1,54 @@
1
1
  "use strict";
2
-
3
- const { existsSync, writeFileSync } = require("fs");
4
- const path = require("path");
5
-
6
- // Keep in sync with NAMESPACE_TO_PACKAGE in src/providers/fa-pro.ts.
7
- const NAMESPACE_TO_PACKAGE = {
8
- brands: "@fortawesome/free-brands-svg-icons",
9
- duotone: "@fortawesome/pro-duotone-svg-icons",
10
- "duotone-light": "@fortawesome/duotone-light-svg-icons",
11
- "duotone-regular": "@fortawesome/duotone-regular-svg-icons",
12
- "duotone-thin": "@fortawesome/duotone-thin-svg-icons",
13
- light: "@fortawesome/pro-light-svg-icons",
14
- regular: "@fortawesome/pro-regular-svg-icons",
15
- "sharp-duotone-light": "@fortawesome/sharp-duotone-light-svg-icons",
16
- "sharp-duotone-regular": "@fortawesome/sharp-duotone-regular-svg-icons",
17
- "sharp-duotone-solid": "@fortawesome/sharp-duotone-solid-svg-icons",
18
- "sharp-duotone-thin": "@fortawesome/sharp-duotone-thin-svg-icons",
19
- "sharp-light": "@fortawesome/sharp-light-svg-icons",
20
- "sharp-regular": "@fortawesome/sharp-regular-svg-icons",
21
- "sharp-solid": "@fortawesome/sharp-solid-svg-icons",
22
- "sharp-thin": "@fortawesome/sharp-thin-svg-icons",
23
- solid: "@fortawesome/pro-solid-svg-icons",
24
- thin: "@fortawesome/pro-thin-svg-icons",
25
- };
26
-
27
- const LEGACY_PACKAGE = "@fortawesome/fontawesome-pro";
28
-
29
- const NODE_MODULES_PATH = process.env.NODE_MODULES_PATH ?? path.join(__dirname, "../../../node_modules");
30
-
31
- const collectIconNames = (pkgName) => {
32
- const pkgPath = path.join(NODE_MODULES_PATH, pkgName);
33
- if (!existsSync(pkgPath)) {
34
- return null;
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ /* eslint-disable no-console */
4
+ const fs_1 = require("fs");
5
+ const path_1 = require("path");
6
+ const _faProTarballCache_1 = require("../src/utils/_faProTarballCache");
7
+ const OUTPUT_FILE = (0, path_1.join)(__dirname, "../src/fa-pro-types.ts");
8
+ /**
9
+ * Regenerate the `FaProIconName` union from the icons the configured Font
10
+ * Awesome package actually ships.
11
+ *
12
+ * The package is the single source of truth on purpose: the file is committed
13
+ * and CI verifies it with `git diff --exit-code`, so a second source (installed
14
+ * `@fortawesome/*-svg-icons` packages, which omit every alias) would make the
15
+ * output depend on what happens to be in `node_modules`.
16
+ */
17
+ async function generate() {
18
+ var _a, _b, _c;
19
+ const source = await (0, _faProTarballCache_1._resolveFaProSource)();
20
+ // The union and the pinned version travel in the same tarball, so they must
21
+ // describe the same archive. Generating from anything else would ship a type
22
+ // that promises icons the runtime will not find (or hide ones it would).
23
+ const expected = (0, _faProTarballCache_1._getFaProDefaultVersion)();
24
+ if (source.version !== expected) {
25
+ throw new Error(`Refusing to generate types from ${source.package}@${source.version} while the package is pinned to ${expected}.\n` +
26
+ `To adopt a new kit: set DEFAULT_VERSION in src/utils/_faProTarballCache.ts to "${source.version}", then run this again.`);
35
27
  }
36
- // eslint-disable-next-line @typescript-eslint/no-require-imports
37
- const pkgExports = require(pkgPath);
38
- const names = new Set();
39
- for (const value of Object.values(pkgExports)) {
40
- if (value && typeof value === "object" && typeof value.iconName === "string") {
41
- names.add(value.iconName);
42
- }
43
- }
44
- return [...names].sort();
45
- };
46
-
47
- const generate = () => {
48
- if (existsSync(path.join(NODE_MODULES_PATH, LEGACY_PACKAGE))) {
49
- throw new Error(
50
- `Package "${LEGACY_PACKAGE}" is installed but no longer used. The faPro adapter reads from per-style packages instead. Run \`yarn remove ${LEGACY_PACKAGE}\`.`,
51
- );
28
+ const index = await (0, _faProTarballCache_1._getFaProIndex)();
29
+ const namespaces = Object.keys(index.icons).sort();
30
+ if (namespaces.length === 0) {
31
+ throw new Error(`${source.package}@${source.version} contains no icon SVGs. Check the package contents.`);
52
32
  }
53
-
54
33
  const names = [];
55
- const found = [];
56
- const missing = [];
57
-
58
- for (const [namespace, pkgName] of Object.entries(NAMESPACE_TO_PACKAGE)) {
59
- const iconNames = collectIconNames(pkgName);
60
- if (iconNames === null) {
61
- missing.push(`${namespace} (${pkgName})`);
62
- continue;
63
- }
64
- found.push(`${namespace}: ${iconNames.length}`);
65
- for (const iconName of iconNames) {
34
+ for (const namespace of namespaces) {
35
+ for (const iconName of (_a = index.icons[namespace]) !== null && _a !== void 0 ? _a : []) {
66
36
  names.push(`"${namespace}.${iconName}"`);
67
37
  }
68
38
  }
69
-
70
- if (names.length === 0) {
71
- throw new Error(
72
- "No Font Awesome per-style packages found. Install at least one, e.g. `yarn add -D @fortawesome/pro-regular-svg-icons`.",
73
- );
39
+ (0, fs_1.writeFileSync)(OUTPUT_FILE, `export type FaProIconName = ${names.join(" | ")};\n`);
40
+ console.log(`Generated ${names.length} icon names from ${source.package}@${source.version}.`);
41
+ for (const namespace of namespaces) {
42
+ console.log(` ${namespace}: ${(_c = (_b = index.icons[namespace]) === null || _b === void 0 ? void 0 : _b.length) !== null && _c !== void 0 ? _c : 0}`);
74
43
  }
75
-
76
- writeFileSync(
77
- path.join(__dirname, "../src/fa-pro-types.ts"),
78
- `export type FaProIconName = ${names.join(" | ")};\n`,
79
- );
80
-
81
- console.log(`Generated ${names.length} FA Pro icon names from ${found.length} package(s).`);
82
- for (const line of found) {
83
- console.log(` ${line}`);
84
- }
85
- if (missing.length > 0) {
86
- console.log(`Skipped (not installed):`);
87
- for (const line of missing) {
88
- console.log(` ${line}`);
89
- }
44
+ }
45
+ generate().catch((error) => {
46
+ console.error(`Failed to generate FA Pro icon types from ${(0, _faProTarballCache_1._getFaProPackage)()}.`);
47
+ // Only guess at the cause when the error is not already explaining itself,
48
+ // otherwise the advice contradicts the message right below it.
49
+ if (error instanceof Error && /\d{3} for |fetch|ENOTFOUND|dist-tag/.test(error.message)) {
50
+ console.error(`The registry could not be reached — check that the package's scope is proxied, see docs/recipes/fontawesome-kit-verdaccio.md.`);
90
51
  }
91
- };
92
-
93
- generate();
52
+ console.error(error);
53
+ process.exitCode = 1;
54
+ });