@heroiclands/package-build 25.6.2 → 25.7.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/CHANGELOG.md +23 -0
- package/README.md +19 -1
- package/bin/content-commands.mjs +64 -79
- package/bin/package-build.mjs +25 -10
- package/ci/wip-workflows.test.mjs +252 -0
- package/content-config.mjs +118 -8
- package/docs/api.md +237 -47
- package/docs/commands.md +99 -35
- package/docs/configuration.md +93 -44
- package/docs/guides/release-and-deploy.md +26 -14
- package/docs/guides/site.md +53 -0
- package/engine/cdn-publish.mjs +164 -6
- package/engine/content-index.mjs +71 -19
- package/engine/content-spans.mjs +18 -1
- package/engine/content-styles.mjs +85 -0
- package/engine/derived-sections.mjs +4 -3
- package/engine/event-views.mjs +6 -4
- package/engine/helpers.mjs +33 -9
- package/engine/index.mjs +1 -0
- package/engine/note-cache.mjs +1107 -0
- package/engine/note-page.mjs +424 -0
- package/engine/pack-config.mjs +47 -4
- package/engine/pathnames.mjs +22 -7
- package/engine/prepared-only.mjs +32 -0
- package/engine/preview-index.mjs +55 -13
- package/engine/site-build.mjs +34 -448
- package/engine/site-config.mjs +33 -4
- package/engine/site-maps.mjs +16 -24
- package/engine/site-origins.mjs +23 -0
- package/engine/site-page.mjs +648 -0
- package/engine/site-render.mjs +142 -10
- package/engine/site-serve.mjs +1 -1
- package/engine/sql-tables.mjs +12 -3
- package/package.json +6 -1
- package/site-theme/static/css/style.css +14 -0
- package/types/content-config.d.mts +34 -0
- package/types/engine/cdn-publish.d.mts +22 -0
- package/types/engine/content-index.d.mts +36 -2
- package/types/engine/content-styles.d.mts +20 -0
- package/types/engine/derived-sections.d.mts +3 -3
- package/types/engine/event-views.d.mts +4 -3
- package/types/engine/helpers.d.mts +18 -1
- package/types/engine/index.d.mts +1 -0
- package/types/engine/note-cache.d.mts +149 -0
- package/types/engine/note-page.d.mts +92 -0
- package/types/engine/pack-config.d.mts +30 -0
- package/types/engine/prepared-only.d.mts +14 -0
- package/types/engine/preview-index.d.mts +35 -0
- package/types/engine/site-build.d.mts +5 -100
- package/types/engine/site-config.d.mts +3 -2
- package/types/engine/site-maps.d.mts +7 -11
- package/types/engine/site-origins.d.mts +9 -0
- package/types/engine/site-page.d.mts +261 -0
- package/types/engine/site-render.d.mts +20 -1
- package/types/engine/sql-tables.d.mts +8 -4
package/docs/commands.md
CHANGED
|
@@ -1324,13 +1324,17 @@ package leaves out as a named asset set.
|
|
|
1324
1324
|
**SYNOPSIS**
|
|
1325
1325
|
|
|
1326
1326
|
```
|
|
1327
|
-
package-build cdn publish --set <file> --name <display name> [--dry-run]
|
|
1327
|
+
package-build cdn publish [--dest internal|cloudflare] --set <file> --name <display name> [--dry-run]
|
|
1328
1328
|
```
|
|
1329
1329
|
|
|
1330
1330
|
**DESCRIPTION**
|
|
1331
1331
|
|
|
1332
|
-
|
|
1333
|
-
|
|
1332
|
+
Publication is manual and separate from site building and deployment. No build
|
|
1333
|
+
or release runs it. `--dest internal` is the default: pictures go to
|
|
1334
|
+
`atlas:/srv/preview/cdn`, served at `https://cdn.internal.heroiclands.org`.
|
|
1335
|
+
`--dest cloudflare` uses the existing R2 bucket served at configured `site.assets`
|
|
1336
|
+
(normally `https://cdn.heroiclands.org`). Each destination uses the same planner,
|
|
1337
|
+
transforms, object keys and publication rules.
|
|
1334
1338
|
|
|
1335
1339
|
Every icon and image under the package's picture roots is uploaded flat, as
|
|
1336
1340
|
`icons/<basename>` or `images/<basename>` — shipped and left-out pictures
|
|
@@ -1339,11 +1343,10 @@ site build gives it. `packageBuild.assetTransform` runs on each file exactly
|
|
|
1339
1343
|
as `package-build assets` runs it, so a picture on the CDN holds the bytes the
|
|
1340
1344
|
staged package holds. SVG is served as `image/svg+xml`.
|
|
1341
1345
|
|
|
1342
|
-
|
|
1343
|
-
that address: `thalorna/images/thorn.webp` is
|
|
1346
|
+
An object's key is its path below the selected CDN origin. For Cloudflare, `thalorna/images/thorn.webp` is
|
|
1344
1347
|
`https://cdn.heroiclands.org/thalorna/images/thorn.webp`.
|
|
1345
1348
|
|
|
1346
|
-
`--set` names the set file, written at `<
|
|
1349
|
+
`--set` names the set file, written at `<selected CDN origin>/<contentPackage>/<file>`.
|
|
1347
1350
|
It lists only the pictures the package leaves out — an address a set does not
|
|
1348
1351
|
list resolves to the shipped copy — chosen by the same rule the stage applies,
|
|
1349
1352
|
`packageBuild.shippingLicenses` included. Its shape is the shipped set's, with
|
|
@@ -1380,9 +1383,32 @@ does not have, and a note naming left-out art that is not on the CDN when the
|
|
|
1380
1383
|
run ends, are warnings at the note's line and column: an art slot under
|
|
1381
1384
|
`data:`, an embed, or a body image.
|
|
1382
1385
|
|
|
1383
|
-
**
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
+
**Internal access.** Install `rsync` and OpenSSH on the publishing machine.
|
|
1387
|
+
The default uses your ordinary `atlas` SSH account, which must have write access
|
|
1388
|
+
to `/srv/preview/cdn`. Keys come from your SSH configuration or agent; the command
|
|
1389
|
+
uses batch mode and requires an already verified host key with
|
|
1390
|
+
`StrictHostKeyChecking=yes`. It uses only rsync's receiver protocol, keeps keys out
|
|
1391
|
+
of arguments and logs, and never deletes existing CDN objects. Transfer failures
|
|
1392
|
+
report the exit code and a bounded, sanitized receiver diagnostic; local staging
|
|
1393
|
+
failures name the operation and filesystem error code. Commands, key material and
|
|
1394
|
+
full child-process errors are omitted.
|
|
1395
|
+
|
|
1396
|
+
For an existing restricted publisher credential, configure an SSH alias with its
|
|
1397
|
+
`User preview-publish`, `IdentityFile` and verified `UserKnownHostsFile`. Then set
|
|
1398
|
+
`CDN_INTERNAL_DESTINATION=your-alias:cdn` in the environment or `.env.local`.
|
|
1399
|
+
The deployed forced command `rrsync -wo -munge /srv/preview` accepts that relative
|
|
1400
|
+
destination; do not repeat `/srv/preview` for this account. The override accepts
|
|
1401
|
+
only an SSH host alias followed by `:cdn` or `:/srv/preview/cdn`. It changes the
|
|
1402
|
+
connection, not the public origin. This command neither installs credentials nor
|
|
1403
|
+
changes server permissions.
|
|
1404
|
+
|
|
1405
|
+
Internal skip checks and set comparisons read the selected internal CDN over
|
|
1406
|
+
HTTPS. An internal dry run uses only those reads: no SSH connection, temporary
|
|
1407
|
+
staging or R2 credentials. The CDN must be reachable from the LAN or VPN.
|
|
1408
|
+
|
|
1409
|
+
**Cloudflare credentials.** With `--dest cloudflare`, the store is the existing
|
|
1410
|
+
S3-compatible bucket, signed with AWS Signature Version 4. Its settings are read
|
|
1411
|
+
from the environment, after `.env.local` and `.env` are loaded:
|
|
1386
1412
|
|
|
1387
1413
|
| Variable | What it is |
|
|
1388
1414
|
| ----------------------- | ------------------------------------------------------------------------- |
|
|
@@ -1391,46 +1417,35 @@ read from the environment, after `.env.local` and `.env` are loaded:
|
|
|
1391
1417
|
| `CDN_ACCESS_KEY_ID` | The access key id of a token that can write the bucket. |
|
|
1392
1418
|
| `CDN_SECRET_ACCESS_KEY` | That token's secret. Never printed. |
|
|
1393
1419
|
|
|
1394
|
-
Setting some but not all of them is an error naming the missing ones. With
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
A workflow calls the command the same way, passing the four values as named
|
|
1399
|
-
secrets in the step's environment:
|
|
1400
|
-
|
|
1401
|
-
```yaml
|
|
1402
|
-
- run: npx package-build cdn publish --set alt-art.json --name "Thalorna — illustrated"
|
|
1403
|
-
env:
|
|
1404
|
-
CDN_ENDPOINT: ${{ secrets.CDN_ENDPOINT }}
|
|
1405
|
-
CDN_BUCKET: ${{ secrets.CDN_BUCKET }}
|
|
1406
|
-
CDN_ACCESS_KEY_ID: ${{ secrets.CDN_ACCESS_KEY_ID }}
|
|
1407
|
-
CDN_SECRET_ACCESS_KEY: ${{ secrets.CDN_SECRET_ACCESS_KEY }}
|
|
1408
|
-
```
|
|
1420
|
+
Setting some but not all of them is an error naming the missing ones. With none
|
|
1421
|
+
set, `--dest cloudflare --dry-run` compares against `site.assets` read-only, and an
|
|
1422
|
+
upload is refused. Internal publication ignores all four R2 settings.
|
|
1409
1423
|
|
|
1410
1424
|
**OPTIONS**
|
|
1411
1425
|
|
|
1412
|
-
| Option | Type | Default
|
|
1413
|
-
| ----------- | ------- |
|
|
1414
|
-
| `--
|
|
1415
|
-
| `--
|
|
1416
|
-
| `--
|
|
1426
|
+
| Option | Type | Default | Description |
|
|
1427
|
+
| ----------- | ------- | ---------- | --------------------------------------------------------------------------- |
|
|
1428
|
+
| `--dest` | string | `internal` | `internal` for atlas; `cloudflare` for the configured R2 bucket. |
|
|
1429
|
+
| `--set` | string | — | Required. The set file's name under the package's CDN root, a `.json` file. |
|
|
1430
|
+
| `--name` | string | — | Required. The set's display name. |
|
|
1431
|
+
| `--dry-run` | boolean | `false` | List what would upload and what is skipped; write nothing. |
|
|
1417
1432
|
|
|
1418
1433
|
**EXIT STATUS**
|
|
1419
1434
|
|
|
1420
1435
|
1 when a picture's file has no address, when a picture fails to upload, when
|
|
1421
|
-
`--set` is `default.json` or a path, when `site.assets` is undeclared,
|
|
1422
|
-
when an upload
|
|
1436
|
+
`--set` is `default.json` or a path, when Cloudflare `site.assets` is undeclared, when an internal destination or
|
|
1437
|
+
planned relative key is unsafe, and when an upload lacks access to its store. Warnings about notes do not change
|
|
1423
1438
|
it. Otherwise 0.
|
|
1424
1439
|
|
|
1425
1440
|
**EXAMPLES**
|
|
1426
1441
|
|
|
1427
1442
|
```
|
|
1428
1443
|
$ package-build cdn publish --set alt-art.json --name "Thalorna — illustrated" --dry-run
|
|
1429
|
-
Dry run: comparing 582 pictures against https://cdn.heroiclands.org, read-only.
|
|
1444
|
+
Dry run: comparing 582 pictures against https://cdn.internal.heroiclands.org, read-only.
|
|
1430
1445
|
would upload thalorna/icons/anvilbdg.svg (969 bytes)
|
|
1431
1446
|
…
|
|
1432
1447
|
would upload thalorna/alt-art.json (582 assets)
|
|
1433
|
-
Would upload 582, skipped 0, failed 0; https://cdn.heroiclands.org/thalorna/alt-art.json lists 582 left-out pictures (would change).
|
|
1448
|
+
Would upload 582, skipped 0, failed 0; https://cdn.internal.heroiclands.org/thalorna/alt-art.json lists 582 left-out pictures (would change).
|
|
1434
1449
|
|
|
1435
1450
|
$ package-build cdn publish --set default.json --name Shipped
|
|
1436
1451
|
package-build: `--set default.json` is refused: `default.json` is the shipped set's name, the fallback every other set is read against. Name the set for its art
|
|
@@ -2685,7 +2700,7 @@ it for search.
|
|
|
2685
2700
|
**SYNOPSIS**
|
|
2686
2701
|
|
|
2687
2702
|
```
|
|
2688
|
-
package-build site build [--out <dir>]
|
|
2703
|
+
package-build site build [--root <domain>] [--out <dir>] [--base-url <url>] [--assets <url>]
|
|
2689
2704
|
```
|
|
2690
2705
|
|
|
2691
2706
|
**DESCRIPTION**
|
|
@@ -2748,6 +2763,11 @@ out in the [site guide](guides/site.md#search).
|
|
|
2748
2763
|
|
|
2749
2764
|
The site's address, title and menu are read before the tree is, so a missing
|
|
2750
2765
|
`homepage` or a cold navigation cache fails with the last good site in place.
|
|
2766
|
+
With [`site.inputs`](configuration.md#local-site-inputs), a local module supplies
|
|
2767
|
+
the selected navigation and text artifacts instead of reading the navigation
|
|
2768
|
+
cache. It receives the effective configuration, runs before content rendering,
|
|
2769
|
+
and may reject canonical navigation drift. Its files are validated before
|
|
2770
|
+
output replacement and written after the renderer clears the site.
|
|
2751
2771
|
Every gate is then checked and reported, and the run stops at the first that
|
|
2752
2772
|
fires, ordered so the report names the cause rather than its symptoms — an
|
|
2753
2773
|
unusable dependency manifest, reported after the links that failed because of
|
|
@@ -2760,9 +2780,44 @@ run fails before the search index is built.
|
|
|
2760
2780
|
|
|
2761
2781
|
`--out <dir>` — the directory that is deployed. Defaults to `build/site`.
|
|
2762
2782
|
|
|
2783
|
+
`--root <domain>` — domain for the build's addresses, defaulting to
|
|
2784
|
+
`internal.heroiclands.org`. The site uses `https://www.<domain>` with the
|
|
2785
|
+
package's existing homepage path. An explicit root also selects
|
|
2786
|
+
`https://cdn.<domain>` over configured `site.assets`; omitting this flag keeps
|
|
2787
|
+
configured assets, or derives the CDN when none are configured. Supply a plain
|
|
2788
|
+
DNS domain without a scheme, path, port, credentials, query or fragment.
|
|
2789
|
+
|
|
2790
|
+
`--base-url <url>` — the absolute HTTP(S) address of this build. Its pathname
|
|
2791
|
+
becomes the effective `site.base`, and must end with `/`; `/` serves the site
|
|
2792
|
+
at the origin's root. Pages, local links, theme files, script fonts and search
|
|
2793
|
+
all use that prefix. Output lands under `<out>/<pathname>/`.
|
|
2794
|
+
|
|
2795
|
+
`--assets <url>` — the absolute HTTP(S) asset root for this build. It may
|
|
2796
|
+
include a path; trailing slashes are trimmed.
|
|
2797
|
+
|
|
2798
|
+
Explicit `--base-url` overrides the root-derived site URL, including its path;
|
|
2799
|
+
explicit `--assets` overrides both root-derived and configured assets. These
|
|
2800
|
+
low-level flags are independent and may be combined with `--root`. Cached
|
|
2801
|
+
navigation links on the canonical Heroic Lands www origin and the brand's
|
|
2802
|
+
license link use the effective site origin. External links and authored content
|
|
2803
|
+
links keep their addresses. Asset references on the exact canonical
|
|
2804
|
+
`https://cdn.heroiclands.org` origin use the effective asset root, preserving
|
|
2805
|
+
the path, query and fragment. Other image origins stay unchanged.
|
|
2806
|
+
The build only writes local output; it neither
|
|
2807
|
+
uploads nor fetches missing dependencies or assets.
|
|
2808
|
+
|
|
2809
|
+
Overrides apply in memory
|
|
2810
|
+
before preflight and rendering; they never rewrite `package.json` or
|
|
2811
|
+
`package-build.config.yaml`. The authored homepage must still pass its usual
|
|
2812
|
+
validation. Both URLs require plain paths without percent escapes, dot
|
|
2813
|
+
segments (`.` or `..`), or doubled slashes, and reject credentials, queries,
|
|
2814
|
+
fragments, whitespace and backslashes.
|
|
2815
|
+
Invalid overrides fail before output is replaced. A site declaring
|
|
2816
|
+
`site.sitemaps` must still be served at `/`.
|
|
2817
|
+
|
|
2763
2818
|
**EXIT STATUS**
|
|
2764
2819
|
|
|
2765
|
-
1 if `package.json` declares no `homepage`, or one that does not end
|
|
2820
|
+
1 if a runtime URL override is invalid. 1 if `package.json` declares no `homepage`, or one that does not end
|
|
2766
2821
|
`/<contentPackage>/`; if the site declares no title, description or `assets`
|
|
2767
2822
|
host; or if the navigation has not been fetched (`package-build deps fetch`
|
|
2768
2823
|
fills the cache and is named in the message). 1 if any gate fires — no
|
|
@@ -2774,6 +2829,15 @@ findings of severity `warning` included.
|
|
|
2774
2829
|
|
|
2775
2830
|
**EXAMPLES**
|
|
2776
2831
|
|
|
2832
|
+
```bash
|
|
2833
|
+
package-build site build \
|
|
2834
|
+
--base-url https://www.internal.heroiclands.org/thalorna/ \
|
|
2835
|
+
--assets https://cdn.internal.heroiclands.org
|
|
2836
|
+
package-build site build \
|
|
2837
|
+
--base-url https://www.internal.heroiclands.org/pr/thalorna/123/thalorna/ \
|
|
2838
|
+
--assets https://cdn.internal.heroiclands.org
|
|
2839
|
+
```
|
|
2840
|
+
|
|
2777
2841
|
```
|
|
2778
2842
|
$ package-build site build
|
|
2779
2843
|
[…] indexing content
|
package/docs/configuration.md
CHANGED
|
@@ -974,23 +974,24 @@ Any other key under `docs.itemFields` is refused:
|
|
|
974
974
|
|
|
975
975
|
**Type:** object · **Optional** · every key defaults to nothing published:
|
|
976
976
|
|
|
977
|
-
| Key | Type | Default
|
|
978
|
-
| ------------------- | -------- |
|
|
979
|
-
| `site.base` | string | `""`
|
|
980
|
-
| `site.title` | string | `""`, required when no manifest title exists
|
|
981
|
-
| `site.assets` | string | `""
|
|
982
|
-
| `site.description` | string | `""`, but required for `site build`
|
|
983
|
-
| `site.packages` | string[] | `[]`
|
|
984
|
-
| `site.pass` | string | `""`
|
|
985
|
-
| `site.passOptions` | object | `{}`
|
|
986
|
-
| `site.notfound` | object | `null`
|
|
987
|
-
| `site.search` | boolean | `true`
|
|
988
|
-
| `site.maps` | boolean | `true`
|
|
989
|
-
| `site.sections` | object | `{}`
|
|
990
|
-
| `site.feed` | string | `""`
|
|
991
|
-
| `site.tags` | boolean | `false`
|
|
992
|
-
| `site.sitemaps` | string[] | `[]`, and only at the root of an origin
|
|
993
|
-
| `site.mergeIndexes` | string[] | `[]`
|
|
977
|
+
| Key | Type | Default |
|
|
978
|
+
| ------------------- | -------- | --------------------------------------------- |
|
|
979
|
+
| `site.base` | string | `""` |
|
|
980
|
+
| `site.title` | string | `""`, required when no manifest title exists |
|
|
981
|
+
| `site.assets` | string | `""`; `site build` derives a CDN when omitted |
|
|
982
|
+
| `site.description` | string | `""`, but required for `site build` |
|
|
983
|
+
| `site.packages` | string[] | `[]` |
|
|
984
|
+
| `site.pass` | string | `""` |
|
|
985
|
+
| `site.passOptions` | object | `{}` |
|
|
986
|
+
| `site.notfound` | object | `null` |
|
|
987
|
+
| `site.search` | boolean | `true` |
|
|
988
|
+
| `site.maps` | boolean | `true` |
|
|
989
|
+
| `site.sections` | object | `{}` |
|
|
990
|
+
| `site.feed` | string | `""` |
|
|
991
|
+
| `site.tags` | boolean | `false` |
|
|
992
|
+
| `site.sitemaps` | string[] | `[]`, and only at the root of an origin |
|
|
993
|
+
| `site.mergeIndexes` | string[] | `[]` |
|
|
994
|
+
| `site.inputs` | string | `""`; optional local input-provider module |
|
|
994
995
|
|
|
995
996
|
The authored content tree determines which pages reach the web. `site` is
|
|
996
997
|
framing: which named pass bundle
|
|
@@ -1016,7 +1017,7 @@ renders it under the deployment root `build/site/`, at
|
|
|
1016
1017
|
|
|
1017
1018
|
> ``package-build config: `site` must be a mapping.``
|
|
1018
1019
|
|
|
1019
|
-
> ``package-build config: `site.<key>` is not a recognized option (expected one of: base, title, assets, description, packages, pass, passOptions, notfound, search, maps, sections, feed, tags, sitemaps, mergeIndexes).``
|
|
1020
|
+
> ``package-build config: `site.<key>` is not a recognized option (expected one of: base, title, assets, description, packages, pass, passOptions, notfound, search, maps, sections, feed, tags, sitemaps, mergeIndexes, inputs).``
|
|
1020
1021
|
|
|
1021
1022
|
`site.assets` is the host every package's imagery is served from, and it is
|
|
1022
1023
|
the one address in this file that is not this repository's own. A note names
|
|
@@ -1029,17 +1030,18 @@ Absolute, and the trailing slash is trimmed:
|
|
|
1029
1030
|
|
|
1030
1031
|
> ``package-build config: `site.assets` must be an absolute `http://` or `https://` address — it is the host every package's imagery is served from, and a relative value resolves against whichever page happens to carry the image.``
|
|
1031
1032
|
|
|
1032
|
-
`package-build site build`
|
|
1033
|
-
|
|
1034
|
-
|
|
1033
|
+
`package-build site build` resolves its effective asset host from `--assets`,
|
|
1034
|
+
an explicit `--root`, or configured `site.assets`, in that order. If none is
|
|
1035
|
+
provided, it derives `https://cdn.internal.heroiclands.org` from the default
|
|
1036
|
+
root. Every relative asset resolves against that effective host.
|
|
1035
1037
|
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1038
|
+
`package-build cdn publish --dest cloudflare` manually uploads pictures under
|
|
1039
|
+
this host, at `<site.assets>/<contentPackage>/icons/<basename>` and
|
|
1040
|
+
`…/images/<basename>`. The R2 bucket is served at `site.assets`, so an object's
|
|
1041
|
+
key is its path below this value. The default `--dest internal` instead publishes
|
|
1042
|
+
the same keys to atlas, served at `https://cdn.internal.heroiclands.org`; its set
|
|
1043
|
+
sources use that internal origin regardless of configured `site.assets`.
|
|
1044
|
+
Publication is separate from site building and deployment.
|
|
1043
1045
|
|
|
1044
1046
|
The site settings carry the same host as
|
|
1045
1047
|
`params.cdnBaseURL`, which the theme resolves a relative asset path against.
|
|
@@ -1284,6 +1286,55 @@ site:
|
|
|
1284
1286
|
mergeIndexes: [sohl, thalorna, kethira, harnensemble]
|
|
1285
1287
|
```
|
|
1286
1288
|
|
|
1289
|
+
[`site build --root <domain>`](commands.md#package-build-site-build) selects
|
|
1290
|
+
`https://www.<domain>` while preserving the homepage path. Its default domain
|
|
1291
|
+
is `internal.heroiclands.org`. Explicit `--root` replaces configured `site.assets`
|
|
1292
|
+
with `https://cdn.<domain>`; without the flag the configured asset host stays,
|
|
1293
|
+
or the derived CDN is used if no asset host is configured. Explicit `--base-url`
|
|
1294
|
+
and `--assets` independently take precedence over these derived values.
|
|
1295
|
+
The effective configuration exposes the chosen address as `homepage`, its path
|
|
1296
|
+
as `site.base`, and the asset host as `site.assets`. The authored configuration
|
|
1297
|
+
stays unchanged and must be valid. A root-website integration uses these resolved
|
|
1298
|
+
inputs rather than deriving hosts itself; canonical source-navigation drift
|
|
1299
|
+
checks remain against the original navigation before projecting its URLs.
|
|
1300
|
+
`readCachedNavigation(effectiveConfig)` projects only canonical Heroic Lands
|
|
1301
|
+
www links onto the effective homepage origin; `siteSettings` does the same for
|
|
1302
|
+
the brand license link. Neither function writes the cache or changes external
|
|
1303
|
+
attribution links.
|
|
1304
|
+
|
|
1305
|
+
### Local site inputs
|
|
1306
|
+
|
|
1307
|
+
`site.inputs` optionally names a local module relative to `rootDir`, such as
|
|
1308
|
+
`utils/site-inputs.mjs`. Use a plain relative path without dot segments,
|
|
1309
|
+
backslashes or symlinks. Its default export is a function taking `{config}`,
|
|
1310
|
+
the immutable effective configuration after root and URL overrides. The function
|
|
1311
|
+
may return a promise and must return `{navigation, files}`:
|
|
1312
|
+
|
|
1313
|
+
```js
|
|
1314
|
+
export default async function ({ config }) {
|
|
1315
|
+
const navigation = [{ name: "Home", url: new URL("/", config.homepage).href }];
|
|
1316
|
+
return { navigation, files: { "nav.json": JSON.stringify(navigation) + "\n" } };
|
|
1317
|
+
}
|
|
1318
|
+
```
|
|
1319
|
+
|
|
1320
|
+
The navigation uses the existing `{name, url, children?}` shape. A provider
|
|
1321
|
+
supplies selected URLs itself; the example reads the effective homepage instead
|
|
1322
|
+
of deriving hosts. A root website can compare its committed canonical navigation
|
|
1323
|
+
against its canonical roster before returning selected-origin navigation. A
|
|
1324
|
+
thrown drift finding stops the build before output is replaced. Without this
|
|
1325
|
+
key the builder continues to require the navigation cache from `deps fetch`.
|
|
1326
|
+
|
|
1327
|
+
`files` maps relative output paths to UTF-8 strings. Paths use plain ASCII
|
|
1328
|
+
letters, numbers, dots, underscores and hyphens within segments, with each
|
|
1329
|
+
segment beginning with a letter or number. Absolute paths, dot segments,
|
|
1330
|
+
symlinks, case collisions and file/directory collisions are refused. A provider
|
|
1331
|
+
cannot claim HTML, theme/static assets, fonts, search/tag trees, page paths,
|
|
1332
|
+
feeds, sitemap files, robots or deployment headers. All files are validated
|
|
1333
|
+
before output replacement, then written inside the package site's output after
|
|
1334
|
+
the renderer clears it. Their paths are included in `written.files`.
|
|
1335
|
+
This prepares build inputs and text artifacts; it is not a shell command or a
|
|
1336
|
+
publication hook.
|
|
1337
|
+
|
|
1287
1338
|
### What the site build reads
|
|
1288
1339
|
|
|
1289
1340
|
`package-build site build` composes the site's settings from sources the
|
|
@@ -1291,17 +1342,17 @@ repository already states, a few constants of the organisation, and the
|
|
|
1291
1342
|
navigation `deps fetch` cached. Every value has one source, and that source is
|
|
1292
1343
|
where it is edited:
|
|
1293
1344
|
|
|
1294
|
-
| Setting | Derived from
|
|
1295
|
-
| -------------------- |
|
|
1296
|
-
| base URL | `package.json` `homepage
|
|
1297
|
-
| title | `site.title` when declared, otherwise `packageBuild.manifest.title`
|
|
1298
|
-
| `params.description` | `site.description`, which is required
|
|
1299
|
-
| `params.author` | the first entry of `authors`, its `name`; absent when `authors` is empty
|
|
1300
|
-
| `params.cdnBaseURL` | `site.assets`, which is required
|
|
1301
|
-
| `params.brand` | the organisation's brand links — `logo`, `licenseURL`, `discordURL` — in `engine/site-config.mjs`
|
|
1302
|
-
| `params.notfound` | `site.notfound`; absent when undeclared
|
|
1303
|
-
| `params.scriptFonts` | the installed script fonts' stylesheet, present only when the package delivers fonts
|
|
1304
|
-
| menu | the navigation `package-build deps fetch` caches from `https://www.heroiclands.org/nav.json`,
|
|
1345
|
+
| Setting | Derived from |
|
|
1346
|
+
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
1347
|
+
| base URL | Effective `homepage` from `siteBuildConfig`; authored `package.json` `homepage` first passes `checkHomepage` |
|
|
1348
|
+
| title | `site.title` when declared, otherwise `packageBuild.manifest.title` |
|
|
1349
|
+
| `params.description` | `site.description`, which is required |
|
|
1350
|
+
| `params.author` | the first entry of `authors`, its `name`; absent when `authors` is empty |
|
|
1351
|
+
| `params.cdnBaseURL` | `site.assets`, which is required |
|
|
1352
|
+
| `params.brand` | the organisation's brand links — `logo`, `licenseURL`, `discordURL` — in `engine/site-config.mjs` |
|
|
1353
|
+
| `params.notfound` | `site.notfound`; absent when undeclared |
|
|
1354
|
+
| `params.scriptFonts` | the installed script fonts' stylesheet, present only when the package delivers fonts |
|
|
1355
|
+
| menu | the navigation `package-build deps fetch` caches from `https://www.heroiclands.org/nav.json`, with canonical owned URLs projected onto the effective homepage origin, a dropdown's entries as its `children` |
|
|
1305
1356
|
|
|
1306
1357
|
The site build reads the navigation from the cache only. A cold cache is an
|
|
1307
1358
|
error naming the command that fills it:
|
|
@@ -1317,11 +1368,9 @@ the same way when it is absent:
|
|
|
1317
1368
|
|
|
1318
1369
|
> ``package-build config: `site.description` is not declared, and the site's `<meta name="description">` reads from it.``
|
|
1319
1370
|
|
|
1320
|
-
`params.cdnBaseURL` reads
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
> ``package-build config: `site.assets` is not declared, and a site build needs one — it is the host every package's imagery is served from, and the theme resolves every relative asset against it.``
|
|
1371
|
+
`params.cdnBaseURL` reads the effective `site.assets` chosen by the build
|
|
1372
|
+
resolver, and the theme resolves every relative asset against it. Direct
|
|
1373
|
+
`siteSettings` callers must supply that effective asset host.
|
|
1325
1374
|
|
|
1326
1375
|
Nothing else is configurable. A site is its homepage and its pages: the
|
|
1327
1376
|
homepage is the package root and every note is a page. A tag is a field a
|
|
@@ -133,23 +133,34 @@ the other actions and environment variables.
|
|
|
133
133
|
|
|
134
134
|
## Publish pictures to the CDN
|
|
135
135
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
136
|
+
Run `package-build cdn publish` manually after pictures or their provenance change.
|
|
137
|
+
It uploads every icon and image flat, applies the stage's transformations, skips
|
|
138
|
+
pictures already present at the same size, and writes a named set listing the
|
|
139
|
+
pictures the Foundry package leaves out. Site builds and releases do not publish
|
|
140
|
+
pictures.
|
|
141
|
+
|
|
142
|
+
The default destination is atlas at `https://cdn.internal.heroiclands.org`:
|
|
140
143
|
|
|
141
144
|
```bash
|
|
142
145
|
package-build cdn publish --set alt-art.json --name "Thalorna — illustrated" --dry-run
|
|
143
146
|
package-build cdn publish --set alt-art.json --name "Thalorna — illustrated"
|
|
144
147
|
```
|
|
145
148
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
149
|
+
Connect to the LAN or VPN. Install rsync and use your verified `atlas` SSH account
|
|
150
|
+
with write access to `/srv/preview/cdn`. SSH configuration or your SSH agent supplies
|
|
151
|
+
the key; unknown host keys fail. For a configured forced-rrsync publisher alias,
|
|
152
|
+
set `CDN_INTERNAL_DESTINATION=your-alias:cdn`; its relative path is required by the
|
|
153
|
+
restricted receiver. The command does not provision keys or change permissions.
|
|
154
|
+
An internal dry run only reads HTTPS; it never opens SSH or uses R2 credentials.
|
|
155
|
+
|
|
156
|
+
To publish to the public CDN, select Cloudflare explicitly:
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
package-build cdn publish --dest cloudflare --set alt-art.json --name "Thalorna — illustrated"
|
|
160
|
+
```
|
|
151
161
|
|
|
152
|
-
|
|
162
|
+
This retains the existing R2 transport and configured `site.assets` origin,
|
|
163
|
+
normally `https://cdn.heroiclands.org`. The bucket's credentials go in `.env.local`:
|
|
153
164
|
|
|
154
165
|
```dotenv
|
|
155
166
|
CDN_ENDPOINT=https://<account id>.r2.cloudflarestorage.com
|
|
@@ -158,10 +169,11 @@ CDN_ACCESS_KEY_ID=<access key id>
|
|
|
158
169
|
CDN_SECRET_ACCESS_KEY=<secret access key>
|
|
159
170
|
```
|
|
160
171
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
172
|
+
With none of those settings present, `--dest cloudflare --dry-run` compares against
|
|
173
|
+
`site.assets` read-only. Both destinations use the same keys and sets; neither
|
|
174
|
+
deletes existing shared CDN objects. See the
|
|
175
|
+
[command reference](../commands.md#package-build-cdn-publish) for SSH setup,
|
|
176
|
+
set shape, refusals and exit status.
|
|
165
177
|
|
|
166
178
|
## Publish a package-build npm version
|
|
167
179
|
|
package/docs/guides/site.md
CHANGED
|
@@ -306,6 +306,59 @@ The terminal reports indexing, rendering, writing and search indexing as they
|
|
|
306
306
|
start, including page counts where available. Progress is on stdout;
|
|
307
307
|
diagnostics retain their file, line and column on stderr.
|
|
308
308
|
|
|
309
|
+
Build locally for the internal site or a public release with the selected root:
|
|
310
|
+
|
|
311
|
+
```bash
|
|
312
|
+
package-build site build --root internal.heroiclands.org
|
|
313
|
+
package-build site build --root heroiclands.org
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
These select `https://www.internal.heroiclands.org` and
|
|
317
|
+
`https://cdn.internal.heroiclands.org`, or `https://www.heroiclands.org` and
|
|
318
|
+
`https://cdn.heroiclands.org`, retaining the package's path. Without `--root`,
|
|
319
|
+
the site defaults to the internal www origin and keeps configured `site.assets`
|
|
320
|
+
(or derives the internal CDN if none is configured). An explicit root overrides
|
|
321
|
+
the configured asset host. Build and publication are separate: this command
|
|
322
|
+
writes local output, reads cached dependencies, and never uploads or fetches
|
|
323
|
+
missing assets. Shared navigation and the brand license follow the selected
|
|
324
|
+
site origin; external attribution and authored content links retain their URLs.
|
|
325
|
+
Asset references to the exact canonical `https://cdn.heroiclands.org` origin
|
|
326
|
+
also use the effective asset root, retaining their path, query and fragment;
|
|
327
|
+
external image hosts keep their addresses. This happens during normal asset
|
|
328
|
+
resolution and leaves authored files unchanged.
|
|
329
|
+
|
|
330
|
+
A site that generates its own navigation can declare
|
|
331
|
+
[`site.inputs`](../configuration.md#local-site-inputs). Its local module receives
|
|
332
|
+
the selected addresses in the effective configuration and returns its menu plus
|
|
333
|
+
text files such as `nav.json`. The builder renders that menu and writes those
|
|
334
|
+
files together, so one build command prepares the complete site. A canonical
|
|
335
|
+
roster check belongs in that module before it returns deployment-specific URLs;
|
|
336
|
+
a drift finding leaves the last built site in place.
|
|
337
|
+
|
|
338
|
+
For a pull request preview, include the whole prefix:
|
|
339
|
+
|
|
340
|
+
```bash
|
|
341
|
+
package-build site build \
|
|
342
|
+
--base-url https://www.internal.heroiclands.org/pr/thalorna/123/thalorna/ \
|
|
343
|
+
--assets https://cdn.internal.heroiclands.org
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
This build writes to `build/site/pr/thalorna/123/thalorna/`. Its local
|
|
347
|
+
links, theme files, script fonts and search stay under that prefix; its images
|
|
348
|
+
use the supplied asset root. `--out` changes the deployment directory above the
|
|
349
|
+
prefix. Explicit `--base-url` takes precedence over the root-derived site
|
|
350
|
+
address, and explicit `--assets` takes precedence over both the root-derived and
|
|
351
|
+
configured asset host. Both URL options are optional and independent, and require absolute
|
|
352
|
+
HTTP(S) URLs. The base URL's path ends with `/`; the asset root may include a
|
|
353
|
+
path and has trailing slashes trimmed. Use plain paths without percent escapes,
|
|
354
|
+
dot segments (`.` or `..`), or doubled slashes, credentials, queries or fragments.
|
|
355
|
+
|
|
356
|
+
The options apply to this build only. Authored `package.json` and YAML stay
|
|
357
|
+
unchanged, and the authored homepage still has to match the configured site.
|
|
358
|
+
Invalid overrides fail before replacing output. A site with `site.sitemaps`
|
|
359
|
+
requires a base URL at the origin's root. See the
|
|
360
|
+
[command reference](../commands.md#package-build-site-build) for URL validation.
|
|
361
|
+
|
|
309
362
|
```bash
|
|
310
363
|
package-build site serve
|
|
311
364
|
```
|