@featherk/icons 0.15.8 → 0.16.1
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 +25 -13
- package/dist/docs-manifest.d.ts +1 -0
- package/dist/docs-manifest.js +7 -5
- package/dist/fontawesome/build.cjs +1 -2
- package/dist/fontawesome/build.d.ts +1 -1
- package/dist/fontawesome/build.mjs +2 -3
- package/dist/fontawesome/catalog.cjs +0 -13
- package/dist/fontawesome/catalog.d.ts +0 -8
- package/dist/fontawesome/catalog.mjs +0 -13
- package/dist/fontawesome/chunks/{generate-BBurrhLv.cjs → generate-B_FxftR7.cjs} +12 -1
- package/dist/fontawesome/chunks/{generate-Zq9q2YZD.mjs → generate-DF9R65sV.mjs} +13 -2
- package/dist/fontawesome/chunks/manifest-CF473fsM.mjs +61 -0
- package/dist/fontawesome/chunks/manifest-DEhGKvmi.cjs +60 -0
- package/dist/fontawesome/cli.cjs +23 -26
- package/dist/fontawesome/cli.mjs +23 -26
- package/dist/fontawesome/generate.d.ts +7 -0
- package/dist/fontawesome/manifest.d.ts +35 -0
- package/dist/fontawesome/setup.cjs +147 -179
- package/dist/fontawesome/setup.d.ts +2 -2
- package/dist/fontawesome/setup.mjs +149 -181
- package/dist/fontawesome/vite.cjs +64 -28
- package/dist/fontawesome/vite.d.ts +25 -5
- package/dist/fontawesome/vite.mjs +65 -29
- package/docs/ADDING-ICONS.md +4 -3
- package/docs/COMING-SOON.md +24 -14
- package/docs/ICONS.md +1 -1
- package/docs/fontawesome/CreateFontAwesomeManifest.md +12 -12
- package/docs/fontawesome/FontAwesome.md +47 -48
- package/docs/fontawesome/FontAwesomeCLI.md +14 -19
- package/docs/fontawesome/FontAwesomeDeveloperSetup.md +134 -0
- package/docs/fontawesome/LICENSING.md +61 -82
- package/package.json +1 -1
- package/dist/fontawesome/chunks/manifest-BB3q10t1.mjs +0 -20
- package/dist/fontawesome/chunks/manifest-C15Xa22L.cjs +0 -19
|
@@ -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` exception, 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
|
|
@@ -20,15 +20,15 @@ The steps below are for Dev after UX/Design has selected the desired Pro variant
|
|
|
20
20
|
|
|
21
21
|
1. Confirm entitlement, Creator coverage, and approved releases with the license owner.
|
|
22
22
|
2. Dev obtains an authorized **Pro Package Token** from the Font Awesome account and supplies it privately as `FONTAWESOME_PACKAGE_TOKEN`.
|
|
23
|
-
3. Dev
|
|
24
|
-
4. Dev
|
|
23
|
+
3. Dev runs `featherk-fontawesome-setup --manifest fontawesome.keys.json`, which pins Free packages into the application and Pro packages into the private `fontawesome-pro-sources/` project at their exact catalog versions. See [Consuming Applications](#consuming-applications).
|
|
24
|
+
4. Dev builds with the application's normal scripts; wherever `fontawesome-pro-sources/` is installed, the builds include the Pro icons.
|
|
25
25
|
5. Dev preserves upstream notices and verifies publication/deployment boundaries before distribution.
|
|
26
26
|
|
|
27
27
|
A package token is not a Kit code, account password, or Kendo license key. Never paste it into chat, screenshots, source files, command arguments, or logs. Follow the organization's approved token issuance/rotation process; do not share account passwords.
|
|
28
28
|
|
|
29
29
|
## This FeatherK Repository
|
|
30
30
|
|
|
31
|
-
Normal root installation/build, Free demos, tests, and public package publishing require no Pro token. `demos/pro` is a separate private source project, not a root workspace. It requests exact `@fortawesome/pro-regular-svg-icons@7.0.0` and `@fortawesome/pro-light-svg-icons@7.0.0` packages; no paid dependency is added to the normal demo workspace or public icons package.
|
|
31
|
+
Normal root installation/build, Free demos, tests, and public package publishing require no Pro token. `demos/fontawesome-pro-sources` is a separate private source project, not a root workspace; it is the same [default layout](#default-isolated-pro-sources) every consuming application uses. It requests exact `@fortawesome/pro-regular-svg-icons@7.0.0` and `@fortawesome/pro-light-svg-icons@7.0.0` packages; no paid dependency is added to the normal demo workspace or public icons package.
|
|
32
32
|
|
|
33
33
|
The committed source-project npm configuration contains only a placeholder:
|
|
34
34
|
|
|
@@ -44,21 +44,21 @@ From the repository root, after confirming Steps 1-2:
|
|
|
44
44
|
```sh
|
|
45
45
|
# The Font Awesome commands run from the built package; build it first.
|
|
46
46
|
npm run build --workspace=@featherk/icons
|
|
47
|
-
# Step 3: Authenticated installation runs only inside demos/pro.
|
|
47
|
+
# Step 3: Authenticated installation runs only inside demos/fontawesome-pro-sources.
|
|
48
48
|
npm run setup:fontawesome:pro --workspace=@featherk/demos
|
|
49
|
-
# Step 4: Start the
|
|
50
|
-
npm run dev
|
|
49
|
+
# Step 4: Start the demo; with the sources installed, the Pro page renders.
|
|
50
|
+
npm run dev --workspace=@featherk/demos
|
|
51
51
|
# Step 5: Build the application and preserve emitted notices.
|
|
52
|
-
npm run build
|
|
52
|
+
npm run build --workspace=@featherk/demos
|
|
53
53
|
```
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
`setup:fontawesome:pro` runs `featherk-fontawesome-setup` without arguments, which installs `demos/fontawesome-pro-sources` from its committed lockfile with `npm ci`. The installer checks for the token without printing it. Review and commit dependency/integrity metadata for reproducible CI, ensuring it contains no credentials. Source `node_modules` and application artifacts remain ignored.
|
|
56
56
|
|
|
57
|
-
The UX-approved Pro manifest requests Regular Rocket, Light Feather, and Light
|
|
57
|
+
The UX-approved Pro manifest requests Regular Rocket, Light Feather, Light Heart, and Light House (`pro-rocket-regular`, `pro-feather-light`, `pro-heart-light`, `pro-house-light`). An authorized installation of these pins succeeded on October 15, 2026 (see [Validation Boundary](#validation-boundary)). If entitlement, releases, or exports later become unavailable, Dev must stop installation/generation and return to UX/Design for approval before changing the manifest or dependencies; never substitute silently.
|
|
58
58
|
|
|
59
|
-
The
|
|
59
|
+
The demo has no separate Pro scripts: its normal `dev` and `build` include the Pro icons once `demos/fontawesome-pro-sources` is installed, and only the Free icons otherwise. `demos/turbo.json` adds `fontawesome-pro-sources/node_modules/.package-lock.json`, which npm writes on install, to the build's cache inputs, so the root Turborepo build never replays a Free build where Pro sources are installed, or the reverse. Do not put paid outputs into shared or remote caches.
|
|
60
60
|
|
|
61
|
-
`
|
|
61
|
+
The demo's plugin options are `{ manifest: "fontawesome.keys.json" }`. With the sources installed, the plugin resolves licensed packages from `fontawesome-pro-sources/` while output guards remain relative to the demo project; Node resolution also finds already installed Free packages in parent workspace directories. Without them, it does not read that directory.
|
|
62
62
|
|
|
63
63
|
Routes are `/icons/fontawesome/free` and `/icons/fontawesome/pro`; `/icons/fontawesome` redirects to Free. The Pro page shows an unavailable state without a licensed profile, never fabricated artwork. Enabling the profile with missing/invalid sources fails the build rather than hiding an error.
|
|
64
64
|
|
|
@@ -77,7 +77,7 @@ setup_status=$?
|
|
|
77
77
|
unset fa_token
|
|
78
78
|
# Step 4: Start only after successful installation.
|
|
79
79
|
if [[ $setup_status -eq 0 ]]; then
|
|
80
|
-
npm run dev
|
|
80
|
+
npm run dev --workspace=@featherk/demos
|
|
81
81
|
fi
|
|
82
82
|
```
|
|
83
83
|
|
|
@@ -96,7 +96,7 @@ try {
|
|
|
96
96
|
Remove-Item Env:FONTAWESOME_PACKAGE_TOKEN -ErrorAction SilentlyContinue
|
|
97
97
|
}
|
|
98
98
|
# Step 4: Start only after successful installation.
|
|
99
|
-
npm run dev
|
|
99
|
+
npm run dev --workspace=@featherk/demos
|
|
100
100
|
```
|
|
101
101
|
|
|
102
102
|
Do not continue after an install error. `401`/`403` can indicate invalid/revoked credentials or insufficient entitlement. Inspect status codes without printing token/config contents. Missing releases/exports need a source/approval review, not an unpinned upgrade.
|
|
@@ -105,11 +105,11 @@ Do not continue after an install error. `401`/`403` can indicate invalid/revoked
|
|
|
105
105
|
|
|
106
106
|
Consumers need their own covered access or an enterprise agreement that actually covers them. The public FeatherK package grants no Pro rights.
|
|
107
107
|
|
|
108
|
-
`@featherk/icons` provides `featherk-fontawesome-setup` for consumer setup. Run it through `npx` or an npm script from the application root,
|
|
108
|
+
`@featherk/icons` provides `featherk-fontawesome-setup` for consumer setup. Run it through `npx` or an npm script from the application root, on a developer machine. It reads the UX-provided keys-only manifest, the same file the Vite plugin and CLI use (a `free` array of catalog keys plus an optional `pro` array), and pins each package to the exact catalog version.
|
|
109
109
|
|
|
110
|
-
###
|
|
110
|
+
### Default: Isolated Pro Sources
|
|
111
111
|
|
|
112
|
-
|
|
112
|
+
Every application uses this layout unless it has a specific reason not to:
|
|
113
113
|
|
|
114
114
|
```sh
|
|
115
115
|
npx featherk-fontawesome-setup --manifest fontawesome.keys.json
|
|
@@ -117,63 +117,54 @@ npx featherk-fontawesome-setup --manifest fontawesome.keys.json
|
|
|
117
117
|
|
|
118
118
|
The command:
|
|
119
119
|
|
|
120
|
-
1.
|
|
120
|
+
1. Installs the exact Free pins into the application's `devDependencies` from public npm. This step needs no token.
|
|
121
|
+
2. Writes the exact Pro pins into `fontawesome-pro-sources/`, a private source project next to the application's `package.json`, then installs it with the token from `FONTAWESOME_PACKAGE_TOKEN` or a hidden prompt. The project contains a `package.json`, a `.gitignore` for its `node_modules`, and an `.npmrc` with only the token placeholder:
|
|
121
122
|
|
|
122
123
|
```ini
|
|
123
124
|
@fortawesome:registry=https://npm.fontawesome.com/
|
|
124
125
|
//npm.fontawesome.com/:_authToken=${FONTAWESOME_PACKAGE_TOKEN}
|
|
125
126
|
```
|
|
126
127
|
|
|
127
|
-
|
|
128
|
+
Commit `package.json`, `package-lock.json`, and `fontawesome-pro-sources/`, including its `package-lock.json`. Configure the Vite plugin with `featherkFontAwesome({ manifest: "fontawesome.keys.json" })`.
|
|
128
129
|
|
|
129
|
-
|
|
130
|
+
The directory name `fontawesome-pro-sources` is fixed, so every team's setup looks the same. The plugin and CLI find the directory themselves, and installing it is what turns Pro icons on. The application's normal `dev` and `build` scripts need no changes:
|
|
130
131
|
|
|
131
|
-
|
|
132
|
+
- **Where `fontawesome-pro-sources/` is installed** (its `node_modules` exists), builds generate the `free` and `pro` keys, resolving Pro packages from it.
|
|
133
|
+
- **Where it is not installed**, builds generate the `free` keys alone and never read it. If a job should have installed it and didn't, code that uses a Pro key fails type checking, because the generated key union then contains only Free keys.
|
|
132
134
|
|
|
133
|
-
|
|
135
|
+
The application's own `npm ci` never needs the token, so developers and CI jobs without Pro access can still install it and build Free-only. Only installing `fontawesome-pro-sources/` needs Pro access, and everyone who does, or who builds where it is installed, needs an applicable seat.
|
|
134
136
|
|
|
135
|
-
|
|
137
|
+
A build cache keyed on tracked files, such as Turborepo's, must also key on whether the sources are installed, or it can replay a Free build where Pro is expected. Add the install marker that npm writes to the build's inputs, for example in Turborepo:
|
|
136
138
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
- `npm rebuild` does not run the application's own lifecycle scripts. Run those explicitly, for example `npm run prepare --if-present`.
|
|
141
|
-
3. Without the token: `npm run dev`, `npm run build`, tests, and deployment. npm runs normally when the `.npmrc` placeholder is unset; only `@fortawesome` registry requests need it.
|
|
139
|
+
```json
|
|
140
|
+
"inputs": ["$TURBO_DEFAULT$", "fontawesome-pro-sources/node_modules/.package-lock.json"]
|
|
141
|
+
```
|
|
142
142
|
|
|
143
|
-
|
|
143
|
+
Keep builds that include Pro icons out of shared or remote caches.
|
|
144
144
|
|
|
145
|
-
|
|
146
|
-
read -r -s -p "Font Awesome package token: " fa_token; echo
|
|
147
|
-
FONTAWESOME_PACKAGE_TOKEN="$fa_token" npm ci --ignore-scripts
|
|
148
|
-
install_status=$?
|
|
149
|
-
unset fa_token
|
|
150
|
-
[[ $install_status -eq 0 ]] && npm rebuild
|
|
151
|
-
```
|
|
145
|
+
After changing the manifest, rerun the same command. It updates both sets of pins; when the Pro pins change, it removes the stale `fontawesome-pro-sources/package-lock.json` and the install regenerates it. Review and commit the result.
|
|
152
146
|
|
|
153
|
-
|
|
147
|
+
On a fresh clone and in CI, run the application's normal `npm ci`, then install the source project from its committed lockfile:
|
|
154
148
|
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
"", (Read-Host "Font Awesome package token" -AsSecureString)
|
|
158
|
-
).Password
|
|
159
|
-
try {
|
|
160
|
-
npm ci --ignore-scripts
|
|
161
|
-
if ($LASTEXITCODE -ne 0) { throw "Font Awesome package installation failed." }
|
|
162
|
-
} finally {
|
|
163
|
-
Remove-Item Env:FONTAWESOME_PACKAGE_TOKEN -ErrorAction SilentlyContinue
|
|
164
|
-
}
|
|
165
|
-
npm rebuild
|
|
149
|
+
```sh
|
|
150
|
+
npx featherk-fontawesome-setup
|
|
166
151
|
```
|
|
167
152
|
|
|
168
|
-
|
|
153
|
+
Without arguments, the command runs `npm ci` in `fontawesome-pro-sources/` with the token, skipping lifecycle scripts and ignoring npm workspace settings. In CI it requires the committed lockfile. See [CI and Deployment](#ci-and-deployment).
|
|
169
154
|
|
|
170
|
-
|
|
155
|
+
### Setup Safety Checks
|
|
156
|
+
|
|
157
|
+
Before supplying the token, the command checks `fontawesome-pro-sources/.npmrc`. It refuses any of the following:
|
|
171
158
|
|
|
172
159
|
- a `@fortawesome` registry other than `https://npm.fontawesome.com/`
|
|
173
160
|
- any reference to `FONTAWESOME_PACKAGE_TOKEN` outside `//npm.fontawesome.com/:_authToken`
|
|
174
161
|
- any other `npm.fontawesome.com` credential, including a literal token
|
|
175
162
|
|
|
176
|
-
It also pins the Font Awesome registry on the npm command line, which overrides other npm configuration
|
|
163
|
+
It also pins the Font Awesome registry on the npm command line, which overrides other npm configuration, so the token can only be sent to Font Awesome. It installs with `--ignore-scripts`, so lifecycle scripts never run while the token is present, passes the token only to that npm process, and never prints it. Setup with `--manifest` changes `package.json`, so it refuses to run in CI.
|
|
164
|
+
|
|
165
|
+
`npm ci` lifecycle scripts and build tools run arbitrary Node code that can read any token in their environment, and log masking does not prevent that. Give the token only to `featherk-fontawesome-setup`, never to the application's `npm ci`, its build, or a whole CI job, and do not export it persistently.
|
|
166
|
+
|
|
167
|
+
The application's own `.npmrc` must not route `@fortawesome` to a registry: Free packages come from public npm, and Pro packages only from `fontawesome-pro-sources/`. Setup refuses an application whose `.npmrc` does. That includes an application set up with the `--pro-in-app` option, which shipped in 0.16.0 and was then removed; remove the Font Awesome lines from its `.npmrc` and any `@fortawesome/pro-*` packages from its `devDependencies`, then rerun setup with `--manifest`.
|
|
177
168
|
|
|
178
169
|
### Exception: Free Only
|
|
179
170
|
|
|
@@ -183,31 +174,20 @@ For an application that will use only Free icons:
|
|
|
183
174
|
npx featherk-fontawesome-setup --manifest fontawesome.keys.json --free-only
|
|
184
175
|
```
|
|
185
176
|
|
|
186
|
-
Free packages come from public npm. The command
|
|
177
|
+
Free packages come from public npm. The command needs no token or CI configuration and creates no source project. The default command behaves the same way for a manifest without Pro keys; `--free-only` also guarantees it, failing if the manifest contains Pro keys, if `fontawesome-pro-sources/` exists, or if `.npmrc` routes `@fortawesome` to a registry. Configure the Vite plugin with `{ manifest: "fontawesome.keys.json" }`. To add Pro later, add the keys to the manifest and rerun without `--free-only`.
|
|
187
178
|
|
|
188
|
-
|
|
179
|
+
### Generation and Licensing Boundaries
|
|
189
180
|
|
|
190
|
-
|
|
181
|
+
Keep Pro keys in the manifest's `pro` group. Public or uncredentialed builds must not include paid inputs: run them where `fontawesome-pro-sources/` is not installed.
|
|
191
182
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
```sh
|
|
195
|
-
# Scaffold .npmrc (token placeholder only), package.json with exact Pro pins, and .gitignore.
|
|
196
|
-
npx featherk-fontawesome-setup --source-root fontawesome-pro-sources --init --manifest fontawesome.keys.json
|
|
197
|
-
# Install with the token; this creates fontawesome-pro-sources/package-lock.json.
|
|
198
|
-
npx featherk-fontawesome-setup --source-root fontawesome-pro-sources
|
|
199
|
-
```
|
|
200
|
-
|
|
201
|
-
Commit the scaffolded files and the lockfile. `--init` pins only Pro keys, because Free packages belong in the application's own `devDependencies`. It refuses to overwrite existing files unless you pass `--force`, and it needs no token. When `--init --force` changes the dependencies, for example by adding a Pro package, it removes the now-stale `package-lock.json`. The next install then regenerates it with `npm install`; review and commit the new lockfile. After editing the source project's `package.json` by hand, run the install with `--refresh-lock` to update the lockfile. Later runs use `npm ci` in the source project and remove npm workspace settings, so `--workspace` invocations target only that project. In CI, `--init` and `--refresh-lock` are refused and the lockfile is required. The application's own `npm ci` needs no token. CI adds a separate token-scoped install step for the source project before the Pro build.
|
|
202
|
-
|
|
203
|
-
Keep Pro keys in the manifest's `pro` group and include them only in the authorized profile. Optional profiles must not silently include paid inputs in public/uncredentialed builds. The `dev:pro`/`build:pro` profile scripts above are repository demo helpers.
|
|
204
|
-
|
|
205
|
-
For non-Vite applications or declaration generation before a standalone type check, follow [CLI and non-Vite setup](FontAwesomeCLI.md). Registry authentication still belongs to the authorized package installation environment; the generator and browser never receive the token. The `allowPro` option prevents accidental selection; it does not verify license entitlement. Follow the [generated-output ignore guidance](FontAwesome.md#generated-output-and-source-checks): exclude generated files from ESLint/Prettier/Git while retaining TypeScript checks.
|
|
183
|
+
For non-Vite applications or declaration generation before a standalone type check, follow [CLI and non-Vite setup](FontAwesomeCLI.md). Registry authentication still belongs to the authorized package installation environment; the generator and browser never receive the token. Listing a key under `pro`, and installing `fontawesome-pro-sources/` only where Pro is wanted, prevent accidental selection; they do not verify license entitlement. Follow the [generated-output ignore guidance](FontAwesome.md#generated-output-and-source-checks): exclude generated files from ESLint/Prettier/Git while retaining TypeScript checks.
|
|
206
184
|
|
|
207
185
|
## CI and Deployment
|
|
208
186
|
|
|
209
187
|
FeatherK and `feather-k-<demo-name>` repositories use GitHub Actions. TeamCity applies only to enterprise apps using that platform.
|
|
210
188
|
|
|
189
|
+
A build that includes Pro icons has three steps: the application's normal `npm ci` without the token, a token-scoped `npx featherk-fontawesome-setup` that installs `fontawesome-pro-sources/` from its lockfile, and the application's normal build without the token. Builds that don't need Pro icons skip the middle step and come out Free-only.
|
|
190
|
+
|
|
211
191
|
Use a dedicated trusted Actions job with a protected Environment and approval/branch rules. Supply the token only to source installation, not public publishing or client compilation. After checkout and Node/root dependency setup:
|
|
212
192
|
|
|
213
193
|
```yaml
|
|
@@ -217,39 +197,38 @@ Use a dedicated trusted Actions job with a protected Environment and approval/br
|
|
|
217
197
|
NPM_CONFIG_CACHE: ${{ runner.temp }}/fontawesome-pro-cache
|
|
218
198
|
run: npm run setup:fontawesome:pro --workspace=@featherk/demos
|
|
219
199
|
- name: Build licensed demo application
|
|
220
|
-
run: npm run build
|
|
200
|
+
run: npm run build --workspace=@featherk/demos
|
|
221
201
|
```
|
|
222
202
|
|
|
223
|
-
In CI, detected from `CI`, `TEAMCITY_VERSION`, or `GITHUB_ACTIONS`, the setup command refuses
|
|
203
|
+
In CI, detected from `CI`, `TEAMCITY_VERSION`, or `GITHUB_ACTIONS`, the setup command refuses `--manifest` setup, and the source-project install requires the committed `package-lock.json`. Unattended jobs therefore only run a locked `npm ci` and never resolve new versions. Supply the token only to the `featherk-fontawesome-setup` step, never to the whole job. With no token and no interactive terminal, the command fails instead of prompting.
|
|
224
204
|
|
|
225
205
|
Configure the protected Environment separately; this fragment grants no license rights. Restrict paid caches/archives/artifacts, and never execute untrusted PR code with the token, including via `pull_request_target`. Normal public FeatherK publishing must not receive Pro credentials or use the licensed profile.
|
|
226
206
|
|
|
227
207
|
### TeamCity
|
|
228
208
|
|
|
229
|
-
Do not define the token as an `env.` parameter. TeamCity passes `env.` parameters to every step in the build, so build tools and lifecycle scripts could read the token. Instead, scope it to
|
|
209
|
+
Do not define the token as an `env.` parameter. TeamCity passes `env.` parameters to every step in the build, so build tools and lifecycle scripts could read the token. Instead, scope it to one install step:
|
|
230
210
|
|
|
231
211
|
1. In the build configuration, add a parameter named `fontawesome.package.token` with type **Password**. Use no `env.` prefix, so TeamCity does not export it to the steps' environment.
|
|
232
|
-
2.
|
|
212
|
+
2. Add a Command Line step that sets the variable for one command only. Each Command Line step runs in its own process, so the variable does not carry into later steps.
|
|
233
213
|
|
|
234
|
-
|
|
214
|
+
Leave the application's existing `npm ci` step unchanged and add this step after it:
|
|
235
215
|
|
|
236
216
|
```sh
|
|
237
|
-
|
|
217
|
+
# Linux agent
|
|
218
|
+
FONTAWESOME_PACKAGE_TOKEN='%fontawesome.package.token%' npx featherk-fontawesome-setup
|
|
238
219
|
```
|
|
239
220
|
|
|
240
|
-
Windows agent:
|
|
241
|
-
|
|
242
221
|
```bat
|
|
222
|
+
rem Windows agent
|
|
243
223
|
set "FONTAWESOME_PACKAGE_TOKEN=%fontawesome.package.token%"
|
|
244
|
-
|
|
224
|
+
npx featherk-fontawesome-setup
|
|
245
225
|
```
|
|
246
226
|
|
|
247
|
-
|
|
248
|
-
4. Leave the build, test, and deploy steps unchanged. They never reference the parameter.
|
|
227
|
+
Leave the build step unchanged: with the sources installed, the normal build includes the Pro icons.
|
|
249
228
|
|
|
250
|
-
|
|
229
|
+
3. Leave the build, test, and deploy steps free of the parameter. They never reference it.
|
|
251
230
|
|
|
252
|
-
|
|
231
|
+
Password parameters are masked in build logs, but masking does not stop code running in a step from reading the value. TeamCity also writes the step script, with the substituted value, to a temporary file on the agent. Limit the parameter to trusted build configurations and agents, and never run untrusted pull-request code in a build that defines it. Build agents must be able to reach `npm.fontawesome.com`. [Free-only](#exception-free-only) applications need no TeamCity configuration.
|
|
253
232
|
|
|
254
233
|
Tokens do not expand Creator seats.
|
|
255
234
|
|
|
@@ -259,6 +238,6 @@ Enterprise Pages must enforce authentication on deployed URLs/static assets; rep
|
|
|
259
238
|
|
|
260
239
|
Public `@featherk/icons` artifacts contain tooling and owned icons only: no paid dependencies/artwork, source caches, credentials, or generated paid-icon collections. Private distribution alone does not establish entitlement.
|
|
261
240
|
|
|
262
|
-
|
|
241
|
+
Automated tests use synthetic packages, so public CI needs no secrets. On October 15, 2026, an authorized installation of `demos/fontawesome-pro-sources` was checked locally: `npm run verify:fontawesome --workspace=@featherk/demos` verified all 14 demo selections, including the four Pro exports, against the installed packages (path data, viewBox, version, and style), and the build emitted both the Free and Pro license notices. Rendering of the Pro page in a browser was not part of that check. Re-run the verification after changing pins. Pro+ collections requiring Kits remain outside this no-Kit implementation.
|
|
263
242
|
|
|
264
|
-
References: [package authentication](https://docs.fontawesome.com/web/setup/packages), [Pro license](https://fontawesome.com/license), and [Font Awesome account](https://fontawesome.com/account).
|
|
243
|
+
References: [package authentication](https://docs.fontawesome.com/web/setup/packages), [Pro license](https://fontawesome.com/license), and [Font Awesome account](https://fontawesome.com/account).
|
package/package.json
CHANGED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { readFile } from "node:fs/promises";
|
|
2
|
-
const isKeyList = (value) => Array.isArray(value) && value.every((key) => typeof key === "string");
|
|
3
|
-
function parseFontAwesomeManifest(manifest) {
|
|
4
|
-
if (!manifest || typeof manifest !== "object" || Array.isArray(manifest)) {
|
|
5
|
-
throw new Error("Font Awesome manifest must be a JSON object");
|
|
6
|
-
}
|
|
7
|
-
const { free, pro } = manifest;
|
|
8
|
-
if (!isKeyList(free) || pro !== void 0 && !isKeyList(pro)) {
|
|
9
|
-
throw new Error(
|
|
10
|
-
'Font Awesome manifest must contain "free" and optional "pro" key arrays'
|
|
11
|
-
);
|
|
12
|
-
}
|
|
13
|
-
return { free, pro: pro ?? [] };
|
|
14
|
-
}
|
|
15
|
-
async function readFontAwesomeManifest(path) {
|
|
16
|
-
return parseFontAwesomeManifest(JSON.parse(await readFile(path, "utf8")));
|
|
17
|
-
}
|
|
18
|
-
export {
|
|
19
|
-
readFontAwesomeManifest as r
|
|
20
|
-
};
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
const promises = require("node:fs/promises");
|
|
3
|
-
const isKeyList = (value) => Array.isArray(value) && value.every((key) => typeof key === "string");
|
|
4
|
-
function parseFontAwesomeManifest(manifest) {
|
|
5
|
-
if (!manifest || typeof manifest !== "object" || Array.isArray(manifest)) {
|
|
6
|
-
throw new Error("Font Awesome manifest must be a JSON object");
|
|
7
|
-
}
|
|
8
|
-
const { free, pro } = manifest;
|
|
9
|
-
if (!isKeyList(free) || pro !== void 0 && !isKeyList(pro)) {
|
|
10
|
-
throw new Error(
|
|
11
|
-
'Font Awesome manifest must contain "free" and optional "pro" key arrays'
|
|
12
|
-
);
|
|
13
|
-
}
|
|
14
|
-
return { free, pro: pro ?? [] };
|
|
15
|
-
}
|
|
16
|
-
async function readFontAwesomeManifest(path) {
|
|
17
|
-
return parseFontAwesomeManifest(JSON.parse(await promises.readFile(path, "utf8")));
|
|
18
|
-
}
|
|
19
|
-
exports.readFontAwesomeManifest = readFontAwesomeManifest;
|