@heroiclands/package-build 22.0.2 → 22.1.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 +79 -0
- package/CONTENT.md +34 -18
- package/README.md +1 -1
- package/bin/content-build.mjs +40 -22
- package/bin/package-build.mjs +34 -0
- package/config.mjs +88 -3
- package/content-config.mjs +246 -12
- package/docs/api.md +10 -7
- package/docs/commands.md +122 -32
- package/docs/configuration.md +257 -62
- package/docs/getting-started.md +15 -4
- package/docs/project-setup.md +45 -20
- package/engine/content-index.mjs +25 -6
- package/engine/pack-config.mjs +21 -2
- package/engine/site-build.mjs +15 -52
- package/engine/site-config.mjs +462 -0
- package/engine/site-root.mjs +165 -0
- package/engine/svg-theme.mjs +140 -0
- package/manifest.mjs +12 -7
- package/package.json +2 -1
- package/stage.mjs +4 -3
- package/types/config.d.mts +80 -33
- package/types/content-config.d.mts +53 -0
- package/types/engine/site-build.d.mts +3 -25
- package/types/engine/site-config.d.mts +223 -0
- package/types/engine/site-root.d.mts +87 -0
- package/types/engine/svg-theme.d.mts +22 -0
- package/types/manifest.d.mts +4 -4
- package/types/stage.d.mts +4 -3
package/docs/configuration.md
CHANGED
|
@@ -28,6 +28,8 @@ two routes, and three keys behave differently depending on which:
|
|
|
28
28
|
| Loaded by | `engine/pack-config.mjs`, which parses the YAML and derives three keys before calling `defineConfig` | `require()`, which loads the module and reads its default export — already the result of the file calling `defineConfig` itself |
|
|
29
29
|
| `rootDir` | Forbidden — always the directory the file sits in | Authored, typically `import.meta.dirname` |
|
|
30
30
|
| `foundryPackage` | Forbidden — always the adjacent `package.json` `name` | Authored |
|
|
31
|
+
| `homepage` | Forbidden — always the adjacent `package.json` `homepage` | Authored |
|
|
32
|
+
| `author` | Forbidden — always the adjacent `package.json` `author` | Authored |
|
|
31
33
|
| `itemBuilders` | A **name** (`sohl`, `hm3`) or list of names, resolved against the registries this package ships | The registry object itself — real builder functions, which only code can carry |
|
|
32
34
|
|
|
33
35
|
A file is chosen by its extension: `package-build.config.yaml`, then
|
|
@@ -46,15 +48,18 @@ around its own evaluation.
|
|
|
46
48
|
|
|
47
49
|
### Quick reference
|
|
48
50
|
|
|
49
|
-
|
|
51
|
+
20 top-level keys. `rootDir` is not one of them — a data configuration never
|
|
50
52
|
writes it — and is documented under [Derived values](#derived-values) instead,
|
|
51
|
-
alongside `foundryPackage` and `itemBuilders`, whose
|
|
52
|
-
behaviour is also derivation rather than ordinary
|
|
53
|
+
alongside `foundryPackage`, `homepage`, `author` and `itemBuilders`, whose
|
|
54
|
+
data-configuration behaviour is also derivation rather than ordinary
|
|
55
|
+
authoring.
|
|
53
56
|
|
|
54
57
|
| Key | Type | Required | Default |
|
|
55
58
|
| ------------------------------------------- | -------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- | ------------------------------------------- |
|
|
56
59
|
| [`contentPackage`](#contentpackage) | string | yes | — |
|
|
57
60
|
| [`foundryPackage`](#foundrypackage) | string | yes (`.mjs` only — derived in YAML); refused in a `documentation` package | — |
|
|
61
|
+
| [`homepage`](#homepage) | string | no (`.mjs` only — derived in YAML) | `null` |
|
|
62
|
+
| [`author`](#author) | string, or `{name, email?, url?}` | no (`.mjs` only — derived in YAML) | `null` |
|
|
58
63
|
| [`packageKind`](#packagekind) | `"systems"` \| `"modules"` \| `"documentation"` | yes | — |
|
|
59
64
|
| [`stats`](#stats) | object | yes; refused in a `documentation` package | — |
|
|
60
65
|
| [`itemBuilders`](#itembuilders) | object, or list of `{system, builders}` (or a name/list of names, in YAML) | no; refused in a `documentation` package | `{}` |
|
|
@@ -74,7 +79,7 @@ behaviour is also derivation rather than ordinary authoring.
|
|
|
74
79
|
|
|
75
80
|
Any key outside this list is refused:
|
|
76
81
|
|
|
77
|
-
> `` `<key>` is not a recognized option (expected one of: rootDir, contentPackage, foundryPackage, packageKind, stats, itemBuilders, paths, skipDirectories, icons, packs, docs, site, pdf, compatibility, relationships, systems, requiresSystem, packageBuild, publish). ``
|
|
82
|
+
> `` `<key>` is not a recognized option (expected one of: rootDir, contentPackage, foundryPackage, homepage, author, packageKind, stats, itemBuilders, paths, skipDirectories, icons, packs, docs, site, pdf, compatibility, relationships, systems, requiresSystem, packageBuild, publish). ``
|
|
78
83
|
|
|
79
84
|
(`rootDir` appears in that list because it is a key `defineConfig` itself
|
|
80
85
|
accepts — an `.mjs` configuration authors it directly. A YAML configuration
|
|
@@ -84,11 +89,11 @@ refuses an authored `rootDir` earlier, with its own message — see
|
|
|
84
89
|
|
|
85
90
|
### Derived values
|
|
86
91
|
|
|
87
|
-
|
|
92
|
+
Seven values in the resolved configuration are never transcribed by an author
|
|
88
93
|
— they are computed from where the file sits, from the adjacent
|
|
89
94
|
`package.json`, from the package kind, or from a name naming a table this
|
|
90
|
-
package already ships. Authoring `rootDir`, `foundryPackage`
|
|
91
|
-
`stats.systemVersion` yourself is an **error**, not an override: a
|
|
95
|
+
package already ships. Authoring `rootDir`, `foundryPackage`, `homepage`,
|
|
96
|
+
`author` or `stats.systemVersion` yourself is an **error**, not an override: a
|
|
92
97
|
transcribed copy is free to drift from what it copied, which is exactly how
|
|
93
98
|
`stats.systemVersion` once sat at a stale version for four releases while
|
|
94
99
|
nothing said so. `assetRoot` has no author-facing spelling to refuse in the
|
|
@@ -130,7 +135,7 @@ which applies before either loader form gets a chance to derive anything.
|
|
|
130
135
|
|
|
131
136
|
If the adjacent `package.json` cannot be read, or declares no `name`:
|
|
132
137
|
|
|
133
|
-
> `package-build: <package.json path> could not be read, and the configuration derives
|
|
138
|
+
> `package-build: <package.json path> could not be read, and the configuration derives its Foundry package id, system version, homepage and author from it.`
|
|
134
139
|
|
|
135
140
|
> ``package-build: <package.json path> declares no `name`, which is what the Foundry package id is derived from.``
|
|
136
141
|
|
|
@@ -143,6 +148,54 @@ which applies before either loader form gets a chance to derive anything.
|
|
|
143
148
|
|
|
144
149
|
> ``package-build config: `foundryPackage` must be a non-empty string.``
|
|
145
150
|
|
|
151
|
+
#### `homepage`
|
|
152
|
+
|
|
153
|
+
The address a package's site is served at — read by the generated Hugo
|
|
154
|
+
configuration for `baseURL`, independently of the Foundry manifest's own
|
|
155
|
+
`url`, which derives from `contentPackage` instead (see
|
|
156
|
+
[`packageBuild.manifest`](#packagebuildmanifest)). `null` when the package
|
|
157
|
+
declares none.
|
|
158
|
+
|
|
159
|
+
- In a **YAML** configuration, writing `homepage:` is refused; the loader
|
|
160
|
+
reads it from the adjacent `package.json` `homepage` instead, verbatim:
|
|
161
|
+
|
|
162
|
+
> ``package-build: <config file> declares `homepage`, which a data configuration may not: it is `package.json`'s own `homepage`. Remove the key.``
|
|
163
|
+
|
|
164
|
+
- In an **`.mjs`** configuration, `homepage` is an ordinary optional key — a
|
|
165
|
+
non-empty string when declared:
|
|
166
|
+
|
|
167
|
+
> ``package-build config: `homepage` must be a non-empty string.``
|
|
168
|
+
|
|
169
|
+
`homepage` is not itself checked against `contentPackage` by `defineConfig`.
|
|
170
|
+
`checkHomepage` in `config.mjs` is the check: `homepage` is required
|
|
171
|
+
unconditionally — every package publishes a site — and must be an absolute
|
|
172
|
+
URL whose path ends `/<contentPackage>/`. `content-build site` makes it
|
|
173
|
+
before the generated `baseURL` is written, so a missing or mismatched
|
|
174
|
+
`homepage` is a finding on every site build:
|
|
175
|
+
|
|
176
|
+
> ``package-build config: `homepage` is not declared in `package.json`, and every package needs one to build its site's `baseURL` from. Add `https://www.heroiclands.org/<contentPackage>/`.``
|
|
177
|
+
|
|
178
|
+
> ``package-build config: `homepage` is `https://www.heroiclands.org/harn-ensemble`, but `contentPackage` is `harnensemble` — a package's site is served at `https://www.heroiclands.org/harnensemble/`, so `package.json`'s `homepage` must end `/harnensemble/`.``
|
|
179
|
+
|
|
180
|
+
#### `author`
|
|
181
|
+
|
|
182
|
+
The package's byline, normalised from either of npm's `author` forms — a
|
|
183
|
+
string (`"Name <email> (url)"`, with the email and the URL both optional) or
|
|
184
|
+
an object (`{name, email?, url?}`) — to the object form. `null` when the
|
|
185
|
+
package declares none.
|
|
186
|
+
|
|
187
|
+
- In a **YAML** configuration, writing `author:` is refused; the loader reads
|
|
188
|
+
it from the adjacent `package.json` `author` instead:
|
|
189
|
+
|
|
190
|
+
> ``package-build: <config file> declares `author`, which a data configuration may not: it is `package.json`'s own `author`. Remove the key.``
|
|
191
|
+
|
|
192
|
+
- In an **`.mjs`** configuration, `author` is an ordinary optional key, in
|
|
193
|
+
either form:
|
|
194
|
+
|
|
195
|
+
> ``package-build config: `author` must be `"Name"`, `"Name <email>"`, `"Name (url)"` or `"Name <email> (url)"` — npm's own `author` forms.``
|
|
196
|
+
|
|
197
|
+
> ``package-build config: `author` must be a string or an object with `name`, `email` and `url`.``
|
|
198
|
+
|
|
146
199
|
#### `assetRoot`
|
|
147
200
|
|
|
148
201
|
The served Foundry asset root a compiled document's `img:` is resolved
|
|
@@ -236,7 +289,7 @@ Unlike the first three, authoring `itemBuilders` is not an error — it is
|
|
|
236
289
|
|
|
237
290
|
---
|
|
238
291
|
|
|
239
|
-
## The
|
|
292
|
+
## The 20 keys
|
|
240
293
|
|
|
241
294
|
### `contentPackage`
|
|
242
295
|
|
|
@@ -282,6 +335,16 @@ package id:
|
|
|
282
335
|
|
|
283
336
|
> ``package-build config: `foundryPackage` is refused in a `documentation` package, which is not a Foundry package, so it has no Foundry package id.``
|
|
284
337
|
|
|
338
|
+
### `homepage`
|
|
339
|
+
|
|
340
|
+
See [Derived values](#derived-values) — forbidden in a YAML configuration,
|
|
341
|
+
optional (a non-empty string) in an `.mjs` one.
|
|
342
|
+
|
|
343
|
+
### `author`
|
|
344
|
+
|
|
345
|
+
See [Derived values](#derived-values) — forbidden in a YAML configuration,
|
|
346
|
+
optional (either of npm's forms) in an `.mjs` one.
|
|
347
|
+
|
|
285
348
|
### `packageKind`
|
|
286
349
|
|
|
287
350
|
**Type:** `"systems"` \| `"modules"` \| `"documentation"` · **Required** · no default.
|
|
@@ -436,16 +499,17 @@ name form resolves before reaching here.
|
|
|
436
499
|
**Type:** object · **Optional** · every key defaults to the conventional
|
|
437
500
|
HeroicLands layout, resolved against `rootDir`:
|
|
438
501
|
|
|
439
|
-
| Key
|
|
440
|
-
|
|
|
441
|
-
| `paths.content`
|
|
442
|
-
| `paths.assets`
|
|
443
|
-
| `paths.contentIndex`
|
|
444
|
-
| `paths.packJson`
|
|
445
|
-
| `paths.stage`
|
|
446
|
-
| `paths.unpack`
|
|
447
|
-
| `paths.foreignCache`
|
|
448
|
-
| `paths.metadataCache`
|
|
502
|
+
| Key | Default | What it is |
|
|
503
|
+
| ----------------------- | ------------------------ | ----------------------------------------------------------------------------------------------- |
|
|
504
|
+
| `paths.content` | `assets/content` | The content tree root. |
|
|
505
|
+
| `paths.assets` | `assets` | The asset roots' parent, holding `icons/`, `images/` and `audio/`. |
|
|
506
|
+
| `paths.contentIndex` | `build/content-index` | Where `content-index` writes this package's note index. Derived and disposable. |
|
|
507
|
+
| `paths.packJson` | `build/packs-json` | Build-only per-entry JSON intermediate. |
|
|
508
|
+
| `paths.stage` | `build/stage/packs` | Compiled LevelDB packs. |
|
|
509
|
+
| `paths.unpack` | `build/tmp/packs` | Where `unpack` extracts JSON back to. |
|
|
510
|
+
| `paths.foreignCache` | `build/cache/foreign` | Where a dependency declaring `itemCatalog: true` is unpacked. |
|
|
511
|
+
| `paths.metadataCache` | `build/cache/metadata` | Where a dependency's published content index is fetched to, for every declared dependency. |
|
|
512
|
+
| `paths.navigationCache` | `build/cache/navigation` | Where the site navigation heroiclands.org publishes is fetched to, for the generated Hugo menu. |
|
|
449
513
|
|
|
450
514
|
Every configured path must be **relative** — an absolute one would escape
|
|
451
515
|
the repository the config anchors:
|
|
@@ -458,7 +522,7 @@ An empty value is refused generically:
|
|
|
458
522
|
|
|
459
523
|
Any other key is refused:
|
|
460
524
|
|
|
461
|
-
> ``package-build config: `paths.<key>` is not a recognized option (expected one of: content, assets, contentIndex, packJson, stage, unpack, foreignCache, metadataCache).``
|
|
525
|
+
> ``package-build config: `paths.<key>` is not a recognized option (expected one of: content, assets, contentIndex, packJson, stage, unpack, foreignCache, metadataCache, navigationCache).``
|
|
462
526
|
|
|
463
527
|
### `skipDirectories`
|
|
464
528
|
|
|
@@ -580,7 +644,9 @@ packs:
|
|
|
580
644
|
|
|
581
645
|
> ``package-build config: `packs` must be an array.``
|
|
582
646
|
|
|
583
|
-
|
|
647
|
+
A package may declare **no** packs. A module that ships assets and compiles
|
|
648
|
+
nothing — alternative art for another package is the case — writes `packs: []`,
|
|
649
|
+
and the manifest carries an empty pack list.
|
|
584
650
|
|
|
585
651
|
Two packs (including companions, anywhere in the tree) may not share a name
|
|
586
652
|
— two packs both named `x` produce:
|
|
@@ -686,36 +752,40 @@ Any other key under `docs.itemFields` is refused:
|
|
|
686
752
|
|
|
687
753
|
**Type:** object · **Optional** · every key defaults to nothing published:
|
|
688
754
|
|
|
689
|
-
| Key | Type | Default
|
|
690
|
-
| ----------------------- | -------- |
|
|
691
|
-
| `site.
|
|
692
|
-
| `site.
|
|
693
|
-
| `site.
|
|
694
|
-
| `site.
|
|
695
|
-
| `site.
|
|
696
|
-
| `site.
|
|
697
|
-
| `site.
|
|
698
|
-
| `site.
|
|
699
|
-
| `site.
|
|
700
|
-
| `site.
|
|
701
|
-
| `site.
|
|
755
|
+
| Key | Type | Default |
|
|
756
|
+
| ----------------------- | -------- | --------------------- |
|
|
757
|
+
| `site.base` | string | `""` |
|
|
758
|
+
| `site.assets` | string | `""` |
|
|
759
|
+
| `site.packages` | string[] | `[]` |
|
|
760
|
+
| `site.sections` | object | `{}` |
|
|
761
|
+
| `site.readmeSections` | object | `{}` |
|
|
762
|
+
| `site.landing` | object | `null` |
|
|
763
|
+
| `site.trees` | array | `[]` |
|
|
764
|
+
| `site.pass` | string | `""` |
|
|
765
|
+
| `site.passOptions` | object | `{}` |
|
|
766
|
+
| `site.backfillSections` | boolean | `false` |
|
|
767
|
+
| `site.list` | object | `{shortcodes: false}` |
|
|
768
|
+
| `site.notfound` | object | `null` |
|
|
769
|
+
| `site.hugo` | object | `{}` |
|
|
702
770
|
|
|
703
771
|
How much of a package reaches the web at all is **not** here — it is
|
|
704
|
-
[`publish.site`](#publish). `site` is framing:
|
|
705
|
-
|
|
706
|
-
the
|
|
707
|
-
|
|
772
|
+
[`publish.site`](#publish). `site` is framing: what a section is called,
|
|
773
|
+
which extra trees are published beside the content, which named pass bundle
|
|
774
|
+
supplies the repository's own body rewrites, and the residue of the
|
|
775
|
+
[generated Hugo configuration](#the-generated-hugo-configuration) that is
|
|
776
|
+
genuinely this repository's own.
|
|
708
777
|
|
|
709
|
-
|
|
778
|
+
Where the Hugo tree is written is not a choice. `content-build site` writes
|
|
779
|
+
the whole Hugo source tree under `build/hugo/` — the generated `hugo.toml`,
|
|
780
|
+
the content mount at `build/hugo/content/`, Hugo's own cache — as a sibling
|
|
781
|
+
of the deployment root `build/site/`, so nothing Hugo reads lands in what is
|
|
782
|
+
published. A `site.out` is refused by name:
|
|
710
783
|
|
|
711
|
-
> ``package-build config: `site
|
|
784
|
+
> ``package-build config: `site.out` is retired — the site build writes its content mount at `build/hugo/content`, beside the generated `hugo.toml`, and the location is not configurable. Remove the key.``
|
|
712
785
|
|
|
713
|
-
`site
|
|
714
|
-
it is refused **at build time** rather than by `defineConfig` (an unset
|
|
715
|
-
value would otherwise resolve to `rootDir` itself, and the tree the build
|
|
716
|
-
wipes on every run would be the working tree):
|
|
786
|
+
> ``package-build config: `site` must be a mapping.``
|
|
717
787
|
|
|
718
|
-
> `site
|
|
788
|
+
> ``package-build config: `site.<key>` is not a recognized option (expected one of: base, assets, packages, sections, readmeSections, landing, trees, pass, passOptions, backfillSections, list, notfound, hugo).``
|
|
719
789
|
|
|
720
790
|
`site.assets` is the host every package's imagery is served from, and it is
|
|
721
791
|
the one address in this file that is not this repository's own. A note names
|
|
@@ -728,11 +798,10 @@ Absolute, and the trailing slash is trimmed:
|
|
|
728
798
|
|
|
729
799
|
> ``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.``
|
|
730
800
|
|
|
731
|
-
The
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
page,
|
|
735
|
-
relative.
|
|
801
|
+
The generated Hugo configuration carries the same host as
|
|
802
|
+
`params.cdnBaseURL`, which the theme resolves a relative asset path against.
|
|
803
|
+
The two are one value read by two readers: the toolchain emits it into a
|
|
804
|
+
page, and the theme joins it onto anything the toolchain left relative.
|
|
736
805
|
|
|
737
806
|
`site.packages` names which content packages' notes the site walks, beyond
|
|
738
807
|
this one's own; `site.pass` names a repository's own body-rewrite bundle
|
|
@@ -804,6 +873,126 @@ unchanged, and `backfillSections` is a plain boolean:
|
|
|
804
873
|
|
|
805
874
|
> ``package-build config: `site.backfillSections` must be a boolean.``
|
|
806
875
|
|
|
876
|
+
`site.list` is how a listing page renders, written into the generated Hugo
|
|
877
|
+
configuration as `params.list`:
|
|
878
|
+
|
|
879
|
+
| Key | Type | Required | Default |
|
|
880
|
+
| ---------------------- | ------- | -------- | ------- |
|
|
881
|
+
| `site.list.shortcodes` | boolean | no | `false` |
|
|
882
|
+
|
|
883
|
+
> ``package-build config: `site.list` must be a mapping.``
|
|
884
|
+
|
|
885
|
+
> ``package-build config: `site.list.shortcodes` must be a boolean.``
|
|
886
|
+
|
|
887
|
+
> ``package-build config: `site.list.<key>` is not a recognized option (expected one of: shortcodes).``
|
|
888
|
+
|
|
889
|
+
`site.notfound` is the wording of the "page not found" page, written into
|
|
890
|
+
the generated Hugo configuration as `params.notfound`. The theme renders
|
|
891
|
+
the page for every site; what a repository supplies is the tagline, the
|
|
892
|
+
noun the body prose calls the site, and the routes back. `tagline` and
|
|
893
|
+
`sitenoun` are required once the block is present — a block declaring only
|
|
894
|
+
links would render the theme's generic wording above this site's routes,
|
|
895
|
+
which reads as two sites:
|
|
896
|
+
|
|
897
|
+
| Key | Type | Required | Default |
|
|
898
|
+
| ----------------------------- | ------ | -------- | ----------------------------------------------------------------------- |
|
|
899
|
+
| `site.notfound.tagline` | string | yes | — |
|
|
900
|
+
| `site.notfound.sitenoun` | string | yes | — |
|
|
901
|
+
| `site.notfound.heroimage` | string | no | none — the theme's default banner, resolved against `params.cdnBaseURL` |
|
|
902
|
+
| `site.notfound.links` | array | no | none — no list of routes back |
|
|
903
|
+
| `site.notfound.links[].title` | string | yes | — |
|
|
904
|
+
| `site.notfound.links[].url` | string | yes | — site-relative (`/`, `/polity/`) or absolute |
|
|
905
|
+
| `site.notfound.links[].text` | string | yes | — |
|
|
906
|
+
|
|
907
|
+
```yaml
|
|
908
|
+
site:
|
|
909
|
+
notfound:
|
|
910
|
+
tagline: This module has one page, and it is not at
|
|
911
|
+
sitenoun: module
|
|
912
|
+
heroimage: images/banners/tapestry-of-dreams.webp
|
|
913
|
+
links:
|
|
914
|
+
- title: Thalorna
|
|
915
|
+
url: https://www.heroiclands.org/thalorna/
|
|
916
|
+
text: The setting whose artwork this module replaces.
|
|
917
|
+
```
|
|
918
|
+
|
|
919
|
+
> ``package-build config: `site.notfound` must be a mapping.``
|
|
920
|
+
|
|
921
|
+
> ``package-build config: `site.notfound.tagline` must be a non-empty string.``
|
|
922
|
+
|
|
923
|
+
> ``package-build config: `site.notfound.links` must be a list.``
|
|
924
|
+
|
|
925
|
+
> ``package-build config: `site.notfound.links[<index>].url` must be a non-empty string.``
|
|
926
|
+
|
|
927
|
+
> ``package-build config: `site.notfound.<key>` is not a recognized option (expected one of: tagline, sitenoun, heroimage, links).``
|
|
928
|
+
|
|
929
|
+
> ``package-build config: `site.notfound.links[<index>].<key>` is not a recognized option (expected one of: title, url, text).``
|
|
930
|
+
|
|
931
|
+
`site.hugo` is a mapping deep-merged over the generated Hugo configuration,
|
|
932
|
+
last — the escape hatch for the one key nobody anticipated. A repository
|
|
933
|
+
whose homepage reproduces a notice whose bare URLs must stand unedited turns
|
|
934
|
+
Goldmark's autolinker off:
|
|
935
|
+
|
|
936
|
+
```yaml
|
|
937
|
+
site:
|
|
938
|
+
hugo:
|
|
939
|
+
markup:
|
|
940
|
+
goldmark:
|
|
941
|
+
extensions:
|
|
942
|
+
linkify: false
|
|
943
|
+
```
|
|
944
|
+
|
|
945
|
+
Objects merge; an array or a scalar replaces what the generator wrote. Every
|
|
946
|
+
key the generator writes is refused here, naming its source — see
|
|
947
|
+
[the generated Hugo configuration](#the-generated-hugo-configuration) — so
|
|
948
|
+
the block cannot grow into a second configuration file:
|
|
949
|
+
|
|
950
|
+
> ``package-build config: `site.hugo` must be a mapping.``
|
|
951
|
+
|
|
952
|
+
> ``package-build config: `site.hugo.baseURL` is derived from package.json `homepage` and must not be declared — it would be overwritten, and the two would disagree with nothing to say so.``
|
|
953
|
+
|
|
954
|
+
### The generated Hugo configuration
|
|
955
|
+
|
|
956
|
+
`content-build site` writes `build/hugo/hugo.toml` on every run. Every value
|
|
957
|
+
in it has one source, and that source is where it is edited:
|
|
958
|
+
|
|
959
|
+
| Key | Derived from |
|
|
960
|
+
| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
961
|
+
| `baseURL` | `package.json` `homepage`, checked by `checkHomepage` — an absolute URL ending `/<contentPackage>/` |
|
|
962
|
+
| `title` | `packageBuild.manifest.title`, which is required |
|
|
963
|
+
| `locale` | the organisation's locale, `en-us`, in `engine/site-config.mjs` |
|
|
964
|
+
| `publishDir` | `contentPackage`, under the deployment root `build/site` — written relative to `build/hugo/`, so `../site/<contentPackage>` |
|
|
965
|
+
| `contentDir` | the fixed content mount, `build/hugo/content` — written as `content` |
|
|
966
|
+
| `themesDir` | where `@heroiclands/hugo-theme` is installed, resolved the way Node resolves a package and written relative to `build/hugo/` |
|
|
967
|
+
| `theme` | the installed `@heroiclands/hugo-theme`, so `hugo-theme` |
|
|
968
|
+
| `disableKinds` | the toolchain, which renders the same kinds on every site: `["taxonomy", "term", "RSS"]` |
|
|
969
|
+
| `params.description` | `package.json` `description`; absent when the package declares none |
|
|
970
|
+
| `params.author` | `package.json` `author`, its `name`; absent when the package declares none |
|
|
971
|
+
| `params.cdnBaseURL` | `site.assets`; absent when unset |
|
|
972
|
+
| `params.brand` | the organisation's brand links — `logo`, `licenseURL`, `discordURL` — in `engine/site-config.mjs` |
|
|
973
|
+
| `params.list` | `site.list` |
|
|
974
|
+
| `params.notfound` | `site.notfound`; absent when undeclared |
|
|
975
|
+
| `markup.goldmark.renderer.unsafe` | the toolchain, whose pages carry raw HTML — a `<figure>` for every image, a `<span>` marking an unresolved link |
|
|
976
|
+
| `menu` | the navigation `content-build deps fetch` caches from `https://www.heroiclands.org/nav.json`, entry for entry, a dropdown's entries as `parent` entries |
|
|
977
|
+
|
|
978
|
+
The site build reads the navigation from the cache only. A cold cache is an
|
|
979
|
+
error naming the command that fills it:
|
|
980
|
+
|
|
981
|
+
> `the site navigation has not been fetched. Run `content-build deps fetch` first.`
|
|
982
|
+
|
|
983
|
+
A missing theme names the package to install:
|
|
984
|
+
|
|
985
|
+
> `@heroiclands/hugo-theme is not installed anywhere above <rootDir> — add it to `devDependencies`and run`npm ci``
|
|
986
|
+
|
|
987
|
+
And a site's title reads from the manifest's, so a configuration declaring
|
|
988
|
+
none fails the site build:
|
|
989
|
+
|
|
990
|
+
> ``package-build config: `packageBuild.manifest.title` is not declared, and the site's `title` reads from it.``
|
|
991
|
+
|
|
992
|
+
Nothing else is emitted. `[taxonomies]` and `[outputs]` are Hugo's defaults
|
|
993
|
+
once the taxonomy kinds and RSS are disabled, and every other key is
|
|
994
|
+
`site.hugo`'s to add.
|
|
995
|
+
|
|
807
996
|
### `pdf`
|
|
808
997
|
|
|
809
998
|
**Type:** object · **Optional** · default `null` (no book is built).
|
|
@@ -1155,7 +1344,7 @@ packageBuild:
|
|
|
1155
1344
|
assetTransform: ./utils/svg-theme.mjs
|
|
1156
1345
|
stageDir: build/stage
|
|
1157
1346
|
clean:
|
|
1158
|
-
extra: [
|
|
1347
|
+
extra: [coverage]
|
|
1159
1348
|
lang:
|
|
1160
1349
|
sources: lang/*.json
|
|
1161
1350
|
deploy:
|
|
@@ -1230,6 +1419,7 @@ say so.
|
|
|
1230
1419
|
| ------------------------------------- | ---------------------------------------------------------------- |
|
|
1231
1420
|
| `packageBuild.manifest.id` | `foundryPackage`, itself derived from `package.json` `name` |
|
|
1232
1421
|
| `packageBuild.manifest.version` | `package.json` `version` |
|
|
1422
|
+
| `packageBuild.manifest.description` | `package.json` `description` |
|
|
1233
1423
|
| `packageBuild.manifest.url` | `package.json` `repository` |
|
|
1234
1424
|
| `packageBuild.manifest.bugs` | `package.json` `repository` |
|
|
1235
1425
|
| `packageBuild.manifest.manifest` | `package.json` `repository` and the release tag |
|
|
@@ -1240,6 +1430,8 @@ say so.
|
|
|
1240
1430
|
|
|
1241
1431
|
> ``package-build config: `packageBuild.manifest.version` is derived from package.json `version` and must not be declared — it would be overwritten, and the two would disagree with nothing to say so.``
|
|
1242
1432
|
|
|
1433
|
+
> ``package-build config: `packageBuild.manifest.description` is derived from package.json `description` and must not be declared — it would be overwritten, and the two would disagree with nothing to say so.``
|
|
1434
|
+
|
|
1243
1435
|
> ``package-build config: `packageBuild.manifest` must be a mapping.``
|
|
1244
1436
|
|
|
1245
1437
|
### `packageBuild.schema`
|
|
@@ -1455,14 +1647,17 @@ the source directory:
|
|
|
1455
1647
|
|
|
1456
1648
|
## Every retired or forbidden key, in one place
|
|
1457
1649
|
|
|
1458
|
-
| Key
|
|
1459
|
-
|
|
|
1460
|
-
| `publish.address.landing`
|
|
1461
|
-
| `packs[].folders`
|
|
1462
|
-
| `rootDir`
|
|
1463
|
-
| `foundryPackage`
|
|
1464
|
-
| `
|
|
1465
|
-
| `stats.
|
|
1466
|
-
| `
|
|
1467
|
-
| `
|
|
1468
|
-
| `
|
|
1650
|
+
| Key | Why |
|
|
1651
|
+
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
1652
|
+
| `publish.address.landing` | Retired — named a whole-section landing, and there are no sections to address. |
|
|
1653
|
+
| `packs[].folders` | Retired — a folder is a note (`type: folder`), materialised by the pack whose documents reference it. |
|
|
1654
|
+
| `rootDir` | Forbidden in a YAML configuration — always the file's own directory. |
|
|
1655
|
+
| `foundryPackage` | Forbidden in a YAML configuration — always the adjacent `package.json` `name`. |
|
|
1656
|
+
| `homepage`, `author` | Forbidden in a YAML configuration — always the adjacent `package.json`'s own `homepage` and `author`. |
|
|
1657
|
+
| `stats.systemId` | Forbidden in every configuration — derived from `packageKind`, `requiresSystem` or a lone declared system. |
|
|
1658
|
+
| `stats.systemVersion` | Forbidden in every configuration — derived from `package.json` (a system) or `systems:` / `relationships.systems` (a module). |
|
|
1659
|
+
| `packageBuild.manifest.id`, `.version`, `.description`, `.url`, `.bugs`, `.manifest`, `.download`, `.compatibility`, `.relationships`, `.packs` | Forbidden — each is derived from `package.json` or the top level of `package-build.config.yaml`; see [`packageBuild.manifest`](#packagebuildmanifest). |
|
|
1660
|
+
| `site.out` | Retired — the site build writes its content mount at `build/hugo/content`, beside the generated `hugo.toml`. |
|
|
1661
|
+
| `site.hugo.baseURL`, `.title`, `.locale`, `.publishDir`, `.contentDir`, `.themesDir`, `.theme`, `.disableKinds`, `.params.description`, `.params.author`, `.params.cdnBaseURL`, `.params.brand`, `.params.list`, `.params.notfound`, `.markup.goldmark.renderer.unsafe`, `.menu` | Forbidden — each is written by the site build from a source it names; see [the generated Hugo configuration](#the-generated-hugo-configuration). |
|
|
1662
|
+
| `publish.site: true` / `publish.site: false` | Refused rather than mapped — write `homepage` or `content`. |
|
|
1663
|
+
| `packs`, `itemBuilders`, `docs`, `compatibility`, `relationships`, `systems`, `requiresSystem`, `stats`, `foundryPackage` | Forbidden in a `documentation` package — each describes a Foundry package this kind is not; see the key's own section for its located refusal message. |
|
package/docs/getting-started.md
CHANGED
|
@@ -769,10 +769,21 @@ for.
|
|
|
769
769
|
Four capabilities are configuration away, and each has its own guide material.
|
|
770
770
|
None of them is needed to build a package.
|
|
771
771
|
|
|
772
|
-
**A website.**
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
772
|
+
**A website.** Every package publishes one — at the least, the homepage note
|
|
773
|
+
from step 5 — at `https://www.heroiclands.org/<contentPackage>/`. Add that
|
|
774
|
+
address to `package.json` as `homepage`, with a `description` and an `author`
|
|
775
|
+
beside it; add `@heroiclands/hugo-theme` under `devDependencies`; and add a
|
|
776
|
+
`packageBuild.manifest.title`. Then `content-build deps fetch` caches the
|
|
777
|
+
organisation's navigation, and `content-build site` writes the whole Hugo
|
|
778
|
+
source tree under `build/hugo/` — the configuration generated from those
|
|
779
|
+
values, and the content mount — for `hugo --source build/hugo` to render
|
|
780
|
+
into `build/site/<contentPackage>/`. There is no Hugo configuration to
|
|
781
|
+
write: the file is generated on every run, and what is genuinely the
|
|
782
|
+
package's own — the wording of its "page not found" page — goes in the
|
|
783
|
+
`site:` block as `site.notfound`. Set `publish.site: content` and name the
|
|
784
|
+
sections under `site.sections`, and the same command publishes the content
|
|
785
|
+
tree's every page beside the homepage. [`project-setup.md`](project-setup.md)
|
|
786
|
+
gives the npm scripts.
|
|
776
787
|
|
|
777
788
|
**Another package's content.** Declare a dependency under `relationships`, and
|
|
778
789
|
`content-build deps fetch` caches that release's published content index so
|
package/docs/project-setup.md
CHANGED
|
@@ -123,9 +123,10 @@ wrong-case import passes locally and fails there.
|
|
|
123
123
|
```
|
|
124
124
|
|
|
125
125
|
`clean` removes the conventional build directories plus anything named in
|
|
126
|
-
`packageBuild.clean.extra` — a
|
|
127
|
-
|
|
128
|
-
|
|
126
|
+
`packageBuild.clean.extra` — a coverage directory, say. Everything the site
|
|
127
|
+
build writes is under `build/`, so a site needs no entry. `distclean`
|
|
128
|
+
additionally removes `node_modules`. Both exit 0 whether or not there was
|
|
129
|
+
anything to remove.
|
|
129
130
|
|
|
130
131
|
### `lint:*` — the checks, one per question
|
|
131
132
|
|
|
@@ -239,12 +240,36 @@ changesets does not touch the lockfile.
|
|
|
239
240
|
|
|
240
241
|
### The site scripts
|
|
241
242
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
243
|
+
Every package publishes a website — at the least, its homepage — so every
|
|
244
|
+
package carries this group:
|
|
245
|
+
|
|
246
|
+
```json
|
|
247
|
+
"build:site": "run-s build:site-content build:site-html build:site-root",
|
|
248
|
+
"build:site-content": "content-build site",
|
|
249
|
+
"build:site-html": "hugo --source build/hugo --minify --gc --cleanDestinationDir",
|
|
250
|
+
"build:site-root": "package-build site-root",
|
|
251
|
+
"serve:site": "npm run build:site-content && hugo server --source build/hugo"
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
`build:site-content` writes the whole Hugo source tree under `build/hugo/` —
|
|
255
|
+
the generated `hugo.toml` and the content mount — with `content-build site`;
|
|
256
|
+
`build:site-html` runs Hugo over it, rendering into `build/site/<contentPackage>/`;
|
|
257
|
+
`build:site-root` writes the deployment's `_headers` and `_redirects` beside
|
|
258
|
+
that; and `serve:site` does the first and then `hugo server` for a live
|
|
259
|
+
preview. The repository carries no Hugo configuration of its own: `hugo.toml`
|
|
260
|
+
is generated on every run from `package.json`, `package-build.config.yaml`,
|
|
261
|
+
the installed `@heroiclands/hugo-theme` and the navigation `deps fetch`
|
|
262
|
+
cached, and the only file to add is `@heroiclands/hugo-theme` under
|
|
263
|
+
`devDependencies`. Hugo itself is a separate install — the extended edition,
|
|
264
|
+
on the developer's `PATH` and the runner's.
|
|
265
|
+
|
|
266
|
+
The site build reads the cached navigation, so `build:site` in a package with
|
|
267
|
+
no other dependency still runs `deps fetch` first:
|
|
268
|
+
|
|
269
|
+
```json
|
|
270
|
+
"build:site": "run-s build:deps build:site-content build:site-html build:site-root",
|
|
271
|
+
"build:deps": "content-build deps fetch"
|
|
272
|
+
```
|
|
248
273
|
|
|
249
274
|
### Deployment scripts
|
|
250
275
|
|
|
@@ -453,17 +478,17 @@ site-deploy workflow, so a fix to any of them reaches every repository at once.
|
|
|
453
478
|
|
|
454
479
|
A summary, because "where does this come from" is the question that recurs.
|
|
455
480
|
|
|
456
|
-
| Read | By
|
|
457
|
-
| -------------------------------------------------- |
|
|
458
|
-
| `package.json` | The Foundry package id, the version, the release addresses. |
|
|
459
|
-
| `package-build.config.yaml` | Everything else about the build.
|
|
460
|
-
| `assets/content/**/*.md` | Every content command.
|
|
461
|
-
| `.gitignore` | `content-build format`, `content-build markdown`.
|
|
462
|
-
| `.prettierignore` | `content-build format`.
|
|
463
|
-
| `.github/labels.yml`, `.github/ISSUE_REPORTING.md` | `package-build labels check`.
|
|
464
|
-
| `lang/*.json` | `package-build lang`.
|
|
465
|
-
| `.env.local` | `package-build deploy`.
|
|
466
|
-
| `.github/workflows/build.yml` | The `pre-push` hook, for its step list.
|
|
481
|
+
| Read | By |
|
|
482
|
+
| -------------------------------------------------- | --------------------------------------------------------------------------------------------------------- |
|
|
483
|
+
| `package.json` | The Foundry package id, the version, the release addresses; the site's `baseURL`, description and author. |
|
|
484
|
+
| `package-build.config.yaml` | Everything else about the build. |
|
|
485
|
+
| `assets/content/**/*.md` | Every content command. |
|
|
486
|
+
| `.gitignore` | `content-build format`, `content-build markdown`. |
|
|
487
|
+
| `.prettierignore` | `content-build format`. |
|
|
488
|
+
| `.github/labels.yml`, `.github/ISSUE_REPORTING.md` | `package-build labels check`. |
|
|
489
|
+
| `lang/*.json` | `package-build lang`. |
|
|
490
|
+
| `.env.local` | `package-build deploy`. |
|
|
491
|
+
| `.github/workflows/build.yml` | The `pre-push` hook, for its step list. |
|
|
467
492
|
|
|
468
493
|
Everything written goes under `build/`. Nothing the toolchain generates is
|
|
469
494
|
committed.
|