@heroiclands/package-build 22.1.0 → 22.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +25 -0
- package/CONTENT.md +22 -0
- package/bin/content-build.mjs +29 -3
- package/bin/package-build.mjs +9 -26
- package/config.mjs +7 -2
- package/content-config.mjs +61 -2
- package/docs/api.md +26 -23
- package/docs/commands.md +22 -22
- package/docs/configuration.md +117 -54
- package/engine/content-links.mjs +19 -9
- package/engine/helpers.mjs +2 -1
- package/engine/metadata-index.mjs +32 -0
- package/engine/note-vocabulary.mjs +20 -0
- package/engine/pack-config.mjs +14 -1
- package/engine/schema-check.mjs +6 -6
- package/engine/site-build.mjs +14 -3
- package/engine/site-config.mjs +68 -27
- package/engine/site-index.mjs +10 -1
- package/engine/web-wikilinks.mjs +16 -6
- package/engine/wikilink-syntax.mjs +10 -0
- package/engine/wikilinks.mjs +34 -7
- package/manifest.mjs +16 -10
- package/package.json +1 -1
- package/release.mjs +41 -8
- package/types/config.d.mts +17 -0
- package/types/content-config.d.mts +11 -0
- package/types/engine/content-links.d.mts +3 -2
- package/types/engine/metadata-index.d.mts +22 -0
- package/types/engine/note-vocabulary.d.mts +12 -0
- package/types/engine/schema-check.d.mts +5 -5
- package/types/engine/site-build.d.mts +5 -1
- package/types/engine/site-config.d.mts +23 -12
- package/types/engine/site-index.d.mts +6 -1
- package/types/engine/web-wikilinks.d.mts +9 -5
- package/types/engine/wikilink-syntax.d.mts +3 -0
- package/types/engine/wikilinks.d.mts +16 -5
- package/types/manifest.d.mts +5 -3
- package/types/release.d.mts +7 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
# @heroiclands/package-build
|
|
2
2
|
|
|
3
|
+
## 22.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 241451e: **`schema.json` is a release asset, not a committed file.** `package-build schema` writes `build/schema.json` instead of the repository root, and `--check` is gone — there is no committed copy left to compare against. `package-build release` publishes `schema.json` beside the archive and the manifest, the way it already publishes the content index, whenever the staged tree carries one.
|
|
8
|
+
|
|
9
|
+
To keep publishing a schema: drop the committed `schema.json` and any lint step that runs `package-build schema --check`; add `{ from: build/schema.json, to: schema.json }` to `packageBuild.assets`, and run `package-build schema` before `package-build assets` in the build chain so the release never ships one older than the source it was cut from.
|
|
10
|
+
- 483b630: **`content-build site` refuses to generate a configuration with no `site.assets`.** The theme resolves every relative asset — the brand logo, the 404 hero, every CDN-resolved image — against `site.assets`, and there is no defensible default: a package that built a site with the key absent published every one of those as a broken relative path. Declare `site.assets` — the `https://` host every package's imagery is served from — in `package-build.config.yaml` for any package that publishes a site.
|
|
11
|
+
- 985f599: **A package now describes itself once for Foundry and once for the site.** Foundry's package browser wants a pitch — HTML, any length — and a site's `<meta name="description">` wants one plain sentence; deriving both from `package.json`'s `description` forced one string onto both. Declare `packageBuild.manifest.descriptionHtml` in `package-build.config.yaml` for the Foundry pitch (HTML allowed, emitted as the manifest's `description`) and `site.description` for the site's meta description (plain text, required for `content-build site`). `package.json`'s own `description` is read by neither any more — a warning names both keys when one is still declared — and the field can be deleted.
|
|
12
|
+
|
|
13
|
+
## 22.1.1
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- f02b25a: **A relationship may declare `contentIndex: false`.** A `requires` or
|
|
18
|
+
`systems` entry naming a package Foundry installs but the content tree never
|
|
19
|
+
cites by wikilink no longer needs a fetched index just to satisfy
|
|
20
|
+
`deps fetch`. `contentIndex` (default `true`) narrows a relationship declaring
|
|
21
|
+
it `false` to the Foundry manifest only: `deps fetch` fetches nothing for it,
|
|
22
|
+
and a wikilink into it fails at the link, naming the key, rather than
|
|
23
|
+
resolving against a stale declaration or an index nobody fetched. It cannot be
|
|
24
|
+
combined with `itemCatalog: true`, which extracts items from the same index
|
|
25
|
+
this declares there is none of.
|
|
26
|
+
- 07bf15d: **The generated Hugo configuration emits tag pages for a site whose notes carry `tags:`.** `content-build site` reads whether any note in the tree carries `tags:` and, when at least one does, writes `[taxonomies] tag = "tags"` and `[outputs] taxonomy = ["HTML"], term = ["HTML"]` into `build/hugo/hugo.toml`, and leaves `taxonomy` and `term` enabled among `disableKinds`. A site whose notes carry no `tags:` gets the same configuration as before — `taxonomy`, `term` and `RSS` all disabled, no `[taxonomies]` or `[outputs]` block. `site.hugo.disableKinds`, `.taxonomies` and `.outputs` stay refused under `site.hugo`, each naming this derivation as the source.
|
|
27
|
+
|
|
3
28
|
## 22.1.0
|
|
4
29
|
|
|
5
30
|
### Minor Changes
|
package/CONTENT.md
CHANGED
|
@@ -1782,6 +1782,28 @@ asked for — a build that downloads silently is not reproducible and fails
|
|
|
1782
1782
|
strangely offline. The cache is keyed by version, so changing the pinned version
|
|
1783
1783
|
is a miss rather than a silent overwrite.
|
|
1784
1784
|
|
|
1785
|
+
### A relationship may be a Foundry dependency only
|
|
1786
|
+
|
|
1787
|
+
`requires` and `systems` install with Foundry whether or not the tree cites
|
|
1788
|
+
them, and a package may need the one without the other — thalornaaltart
|
|
1789
|
+
`requires` Thalorna so Foundry installs the base module, and its one homepage
|
|
1790
|
+
note links nowhere. Declare `contentIndex: false` on that entry to say so:
|
|
1791
|
+
|
|
1792
|
+
```yaml
|
|
1793
|
+
relationships:
|
|
1794
|
+
requires:
|
|
1795
|
+
- id: thalorna
|
|
1796
|
+
type: module
|
|
1797
|
+
manifest: https://github.com/HeroicLands/thalorna/releases/latest/download/module.json
|
|
1798
|
+
contentIndex: false
|
|
1799
|
+
```
|
|
1800
|
+
|
|
1801
|
+
`deps fetch` fetches nothing for it — no cache directory, nothing to go stale —
|
|
1802
|
+
and a wikilink into it fails at the link, naming `contentIndex`, rather than
|
|
1803
|
+
resolving against a stale declaration or an index nobody fetched. It cannot be
|
|
1804
|
+
combined with `itemCatalog: true`, which extracts items from the same index
|
|
1805
|
+
this declares there is none of.
|
|
1806
|
+
|
|
1785
1807
|
### `packagebuild` needs no declaration
|
|
1786
1808
|
|
|
1787
1809
|
package-build ships a set of images of its own — section banners chiefly — and a
|
package/bin/content-build.mjs
CHANGED
|
@@ -1492,7 +1492,10 @@ function pdfCommand() {
|
|
|
1492
1492
|
* **The Hugo configuration is generated before anything is written.** Its
|
|
1493
1493
|
* sources — `package.json`'s `homepage`, the cached navigation, the installed
|
|
1494
1494
|
* theme — are each a way the build can fail, and failing before the output
|
|
1495
|
-
* tree is cleared leaves the last good site in place to be looked at.
|
|
1495
|
+
* tree is cleared leaves the last good site in place to be looked at. It is
|
|
1496
|
+
* generated again once the site walk completes, because whether the site
|
|
1497
|
+
* emits taxonomy pages is read from the walk — whether any note carries
|
|
1498
|
+
* `tags:` — and that is not known until then.
|
|
1496
1499
|
*
|
|
1497
1500
|
* **Each gate is reported and the run stops at the first that fires.** They are
|
|
1498
1501
|
* ordered so the report names the cause rather than its symptoms: an unusable
|
|
@@ -1510,7 +1513,14 @@ function siteCommand() {
|
|
|
1510
1513
|
handler: async () => {
|
|
1511
1514
|
try {
|
|
1512
1515
|
const config = loadPackConfig();
|
|
1513
|
-
|
|
1516
|
+
// Generated once before the walk, purely to fail fast on a
|
|
1517
|
+
// missing or mismatched source — `homepage`, the manifest
|
|
1518
|
+
// title, the cached navigation, the installed theme — while
|
|
1519
|
+
// the last good site is still in place to be looked at. Its
|
|
1520
|
+
// `disableKinds`/`taxonomies`/`outputs` are provisional: only
|
|
1521
|
+
// the site walk below knows whether any note carries `tags:`,
|
|
1522
|
+
// so the value actually written is regenerated after it runs.
|
|
1523
|
+
generateHugoConfig(config);
|
|
1514
1524
|
const result = buildSite({
|
|
1515
1525
|
config,
|
|
1516
1526
|
sqlTables: await prepareTreeSqlTables(config.paths.content, {
|
|
@@ -1628,6 +1638,7 @@ function siteCommand() {
|
|
|
1628
1638
|
`${s.tree ?? 0} tree page(s) + ${s.landings} ` +
|
|
1629
1639
|
`landing(s) to ${path.relative(process.cwd(), s.out)}`,
|
|
1630
1640
|
);
|
|
1641
|
+
const hugo = generateHugoConfig(config, { hasTags: result.hasTags });
|
|
1631
1642
|
const { file } = writeHugoConfig(config, hugo);
|
|
1632
1643
|
log.info(`wrote ${path.relative(process.cwd(), file)}`);
|
|
1633
1644
|
} catch (err) {
|
|
@@ -1860,7 +1871,22 @@ function depsCommand() {
|
|
|
1860
1871
|
if (indexes) log.info(`Fetched ${indexes} dependency content index(es).`);
|
|
1861
1872
|
const count = await fetchAllCatalogs(config);
|
|
1862
1873
|
if (count) log.info(`Fetched ${count} dependency catalogue(s).`);
|
|
1863
|
-
if (!indexes && !count)
|
|
1874
|
+
if (!indexes && !count) {
|
|
1875
|
+
// Distinguished from a package declaring nothing at all: a
|
|
1876
|
+
// relationship may still be declared, just narrowed to the
|
|
1877
|
+
// Foundry manifest by `contentIndex: false` — reporting
|
|
1878
|
+
// "no dependencies" there would read as though the
|
|
1879
|
+
// declaration itself had gone missing.
|
|
1880
|
+
const declared = Object.values(config.relationships ?? {}).some(
|
|
1881
|
+
(entries) => entries?.length,
|
|
1882
|
+
);
|
|
1883
|
+
log.info(
|
|
1884
|
+
declared ?
|
|
1885
|
+
"No declared dependency needs a fetched content index or item " +
|
|
1886
|
+
"catalogue."
|
|
1887
|
+
: "This package declares no dependencies.",
|
|
1888
|
+
);
|
|
1889
|
+
}
|
|
1864
1890
|
} catch (err) {
|
|
1865
1891
|
reportFailure(err);
|
|
1866
1892
|
process.exitCode = 1;
|
package/bin/package-build.mjs
CHANGED
|
@@ -334,9 +334,11 @@ async function formatGenerated(text, filepath) {
|
|
|
334
334
|
* so the system publishes the field sets as data — the same shape the link
|
|
335
335
|
* manifest already uses for addresses.
|
|
336
336
|
*
|
|
337
|
-
*
|
|
338
|
-
*
|
|
339
|
-
*
|
|
337
|
+
* Writes under `build/`, alongside every other generated artifact: a release
|
|
338
|
+
* publishes it beside the archive and the manifest (see `package-build
|
|
339
|
+
* release`), and `packageBuild.assets` carries it into the staged tree from
|
|
340
|
+
* there. There is nothing committed to compare it against, so there is no
|
|
341
|
+
* `--check`.
|
|
340
342
|
*
|
|
341
343
|
* @returns {object} The yargs command module.
|
|
342
344
|
*/
|
|
@@ -344,15 +346,8 @@ function schemaCommand() {
|
|
|
344
346
|
return {
|
|
345
347
|
command: "schema",
|
|
346
348
|
describe: "Publish this package's DataModel field sets as schema.json",
|
|
347
|
-
builder: (y) =>
|
|
348
|
-
|
|
349
|
-
type: "boolean",
|
|
350
|
-
default: false,
|
|
351
|
-
describe:
|
|
352
|
-
"Fail when the committed schema.json is out of date " +
|
|
353
|
-
"rather than rewriting it",
|
|
354
|
-
}),
|
|
355
|
-
handler: handler(async (argv) => {
|
|
349
|
+
builder: (y) => y,
|
|
350
|
+
handler: handler(async () => {
|
|
356
351
|
const config = loadPackageBuildConfig();
|
|
357
352
|
if (!config.schema.length) {
|
|
358
353
|
console.log(
|
|
@@ -369,25 +364,13 @@ function schemaCommand() {
|
|
|
369
364
|
version: pkg.version,
|
|
370
365
|
});
|
|
371
366
|
|
|
372
|
-
const out = path.join(config.rootDir, SCHEMA_ARTIFACT_FILE);
|
|
367
|
+
const out = path.join(config.rootDir, "build", SCHEMA_ARTIFACT_FILE);
|
|
373
368
|
const text = await formatGenerated(JSON.stringify(artifact), out);
|
|
374
369
|
const counts = Object.entries(artifact.documents)
|
|
375
370
|
.map(([kind, subtypes]) => `${Object.keys(subtypes).length} ${kind}`)
|
|
376
371
|
.join(", ");
|
|
377
372
|
|
|
378
|
-
|
|
379
|
-
const current = fs.existsSync(out) ? fs.readFileSync(out, "utf8") : null;
|
|
380
|
-
if (current !== text) {
|
|
381
|
-
die(
|
|
382
|
-
`${SCHEMA_ARTIFACT_FILE} does not match what this ` +
|
|
383
|
-
`package's data models would produce — regenerate ` +
|
|
384
|
-
`it with \`package-build schema\`.`,
|
|
385
|
-
);
|
|
386
|
-
}
|
|
387
|
-
console.log(`✅ ${SCHEMA_ARTIFACT_FILE} is up to date ` + `(${counts} subtypes).`);
|
|
388
|
-
return;
|
|
389
|
-
}
|
|
390
|
-
|
|
373
|
+
fs.mkdirSync(path.dirname(out), { recursive: true });
|
|
391
374
|
fs.writeFileSync(out, text, "utf8");
|
|
392
375
|
console.log(
|
|
393
376
|
`✅ Wrote ${SCHEMA_ARTIFACT_FILE} for ${artifact.system} ` +
|
package/config.mjs
CHANGED
|
@@ -91,7 +91,7 @@ const SECTION_KEYS = [
|
|
|
91
91
|
export const DERIVED_MANIFEST_KEYS = Object.freeze({
|
|
92
92
|
id: "`foundryPackage`, itself derived from package.json `name`",
|
|
93
93
|
version: "package.json `version`",
|
|
94
|
-
description: "
|
|
94
|
+
description: "`packageBuild.manifest.descriptionHtml`",
|
|
95
95
|
url: "package.json `repository`",
|
|
96
96
|
bugs: "package.json `repository`",
|
|
97
97
|
manifest: "package.json `repository` and the release tag",
|
|
@@ -152,11 +152,16 @@ const ARTIFACT_OF_KIND = Object.freeze({
|
|
|
152
152
|
* message, so {@link loadPackageBuildConfig} — the half that knows which file
|
|
153
153
|
* was read — can resolve it to a line and column. This half stays pure.
|
|
154
154
|
*
|
|
155
|
+
* Exported so a sibling module composing a configuration value this module
|
|
156
|
+
* does not itself validate — {@link module:engine/site-config}'s
|
|
157
|
+
* `hugoConfig`, checking `site.assets` — reports through the one helper
|
|
158
|
+
* rather than a second copy.
|
|
159
|
+
*
|
|
155
160
|
* @param {string} where - Dotted path of the offending key.
|
|
156
161
|
* @param {string} problem - What is wrong with it.
|
|
157
162
|
* @returns {never}
|
|
158
163
|
*/
|
|
159
|
-
function fail(where, problem) {
|
|
164
|
+
export function fail(where, problem) {
|
|
160
165
|
throw Object.assign(new TypeError(`package-build config: \`${where}\` ${problem}.`), {
|
|
161
166
|
field: where,
|
|
162
167
|
});
|
package/content-config.mjs
CHANGED
|
@@ -503,6 +503,14 @@ export function publishesContentPages(config) {
|
|
|
503
503
|
* package this one targets — for a system
|
|
504
504
|
* relationship, `verified` is what
|
|
505
505
|
* `_stats.systemVersion` is stamped from.
|
|
506
|
+
* @property {boolean} [contentIndex] Whether `deps fetch` fetches this
|
|
507
|
+
* dependency's content index. Default
|
|
508
|
+
* `true`. `false` declares the dependency
|
|
509
|
+
* for the Foundry manifest only — nothing
|
|
510
|
+
* this tree cites by wikilink — and refuses
|
|
511
|
+
* `itemCatalog: true` on the same entry,
|
|
512
|
+
* since a catalogue is fetched from the same
|
|
513
|
+
* index.
|
|
506
514
|
*/
|
|
507
515
|
|
|
508
516
|
/**
|
|
@@ -751,6 +759,7 @@ const DOCS_KEYS = ["itemFields"];
|
|
|
751
759
|
const SITE_KEYS = [
|
|
752
760
|
"base",
|
|
753
761
|
"assets",
|
|
762
|
+
"description",
|
|
754
763
|
"packages",
|
|
755
764
|
"sections",
|
|
756
765
|
"readmeSections",
|
|
@@ -780,6 +789,7 @@ const RELATIONSHIP_KEYS = [
|
|
|
780
789
|
"manifest",
|
|
781
790
|
"compatibility",
|
|
782
791
|
"itemCatalog",
|
|
792
|
+
"contentIndex",
|
|
783
793
|
];
|
|
784
794
|
const AUTHOR_KEYS = ["name", "email", "url"];
|
|
785
795
|
const ITEM_BUILDER_KEYS = ["system", "img", "fields"];
|
|
@@ -1566,6 +1576,33 @@ function normalizeSiteAssets(value) {
|
|
|
1566
1576
|
return assets.replace(/\/+$/, "");
|
|
1567
1577
|
}
|
|
1568
1578
|
|
|
1579
|
+
/**
|
|
1580
|
+
* The site's `<meta name="description">`, plain text.
|
|
1581
|
+
*
|
|
1582
|
+
* Foundry's package browser wants a pitch — HTML, any length,
|
|
1583
|
+
* `packageBuild.manifest.descriptionHtml` — and a `<meta>` tag wants one
|
|
1584
|
+
* plain sentence. The two audiences are different enough that one string
|
|
1585
|
+
* cannot serve both, so this is the site's own, checked for markup rather
|
|
1586
|
+
* than trusted to carry none: a value with a `<` in it is refused, naming
|
|
1587
|
+
* `descriptionHtml` as where markup belongs.
|
|
1588
|
+
*
|
|
1589
|
+
* @param {unknown} value - The configured value, or `undefined`.
|
|
1590
|
+
* @returns {string} The description; `""` when unset.
|
|
1591
|
+
*/
|
|
1592
|
+
function normalizeSiteDescription(value) {
|
|
1593
|
+
if (value === undefined) return "";
|
|
1594
|
+
const description = requireNonEmptyString(value, "site.description");
|
|
1595
|
+
if (description.includes("<")) {
|
|
1596
|
+
fail(
|
|
1597
|
+
"site.description",
|
|
1598
|
+
"contains `<` — this is plain text for the site's " +
|
|
1599
|
+
'`<meta name="description">`; markup belongs in ' +
|
|
1600
|
+
"`packageBuild.manifest.descriptionHtml`",
|
|
1601
|
+
);
|
|
1602
|
+
}
|
|
1603
|
+
return description;
|
|
1604
|
+
}
|
|
1605
|
+
|
|
1569
1606
|
/**
|
|
1570
1607
|
* A map of section name → landing metadata.
|
|
1571
1608
|
*
|
|
@@ -1604,8 +1641,10 @@ export const DERIVED_HUGO_KEYS = Object.freeze({
|
|
|
1604
1641
|
contentDir: "the fixed content mount, `build/hugo/content`",
|
|
1605
1642
|
themesDir: "where `@heroiclands/hugo-theme` is installed",
|
|
1606
1643
|
theme: "the installed `@heroiclands/hugo-theme`",
|
|
1607
|
-
disableKinds: "
|
|
1608
|
-
|
|
1644
|
+
disableKinds: "whether any note in the tree carries `tags:`, which the site walk discovers",
|
|
1645
|
+
taxonomies: "whether any note in the tree carries `tags:`, which the site walk discovers",
|
|
1646
|
+
outputs: "whether any note in the tree carries `tags:`, which the site walk discovers",
|
|
1647
|
+
"params.description": "`site.description`",
|
|
1609
1648
|
"params.author": "package.json `author`",
|
|
1610
1649
|
"params.cdnBaseURL": "`site.assets`",
|
|
1611
1650
|
"params.brand": "the organisation's brand links, in `engine/site-config.mjs`",
|
|
@@ -1728,6 +1767,7 @@ function normalizeSite(value) {
|
|
|
1728
1767
|
const empty = Object.freeze({
|
|
1729
1768
|
base: "",
|
|
1730
1769
|
assets: "",
|
|
1770
|
+
description: "",
|
|
1731
1771
|
packages: Object.freeze([]),
|
|
1732
1772
|
sections: Object.freeze({}),
|
|
1733
1773
|
readmeSections: Object.freeze({}),
|
|
@@ -1796,6 +1836,7 @@ function normalizeSite(value) {
|
|
|
1796
1836
|
return Object.freeze({
|
|
1797
1837
|
base: input.base === undefined ? "" : requireNonEmptyString(input.base, "site.base"),
|
|
1798
1838
|
assets: normalizeSiteAssets(input.assets),
|
|
1839
|
+
description: normalizeSiteDescription(input.description),
|
|
1799
1840
|
packages: Object.freeze(packages),
|
|
1800
1841
|
sections: normalizeSectionMap(input.sections, "site.sections"),
|
|
1801
1842
|
readmeSections: normalizeSectionMap(input.readmeSections, "site.readmeSections"),
|
|
@@ -2147,6 +2188,24 @@ function normalizeRelationships(value) {
|
|
|
2147
2188
|
}
|
|
2148
2189
|
spec.itemCatalog = rel.itemCatalog;
|
|
2149
2190
|
}
|
|
2191
|
+
// Opt-out: declares the dependency for the Foundry manifest
|
|
2192
|
+
// only, so `deps fetch` fetches no content index for it and a
|
|
2193
|
+
// wikilink into it is refused rather than silently dead. A
|
|
2194
|
+
// catalogue is fetched from the same index, so it cannot be
|
|
2195
|
+
// declared alongside `itemCatalog: true`.
|
|
2196
|
+
if (rel.contentIndex !== undefined) {
|
|
2197
|
+
if (typeof rel.contentIndex !== "boolean") {
|
|
2198
|
+
fail(`${at}.contentIndex`, "must be true or false");
|
|
2199
|
+
}
|
|
2200
|
+
if (rel.contentIndex === false && spec.itemCatalog) {
|
|
2201
|
+
fail(
|
|
2202
|
+
`${at}.contentIndex`,
|
|
2203
|
+
"cannot be false together with `itemCatalog: true` — a catalogue is " +
|
|
2204
|
+
"fetched from the same index",
|
|
2205
|
+
);
|
|
2206
|
+
}
|
|
2207
|
+
spec.contentIndex = rel.contentIndex;
|
|
2208
|
+
}
|
|
2150
2209
|
return Object.freeze(spec);
|
|
2151
2210
|
}),
|
|
2152
2211
|
);
|
package/docs/api.md
CHANGED
|
@@ -342,6 +342,7 @@ The closed half of a note's frontmatter: the `data:` container and each type's `
|
|
|
342
342
|
| `applicableTagGroups` | `applicableTagGroups(type, groups)` | `object[]` | reading the declared tag groups that apply to a note type |
|
|
343
343
|
| `exclusiveTagGroups` | `exclusiveTagGroups(type, groups)` | `Array<{slot, tags}>` | reading the single-valued tag slots a note type has, such as a being's kind |
|
|
344
344
|
| `hasTag` | `hasTag(fm, tag)` | `boolean` | checking whether a note carries a given tag, whatever scalar-or-list form it was authored in |
|
|
345
|
+
| `hasAnyTag` | `hasAnyTag(fm)` | `boolean` | checking whether a note carries any `tags:` at all, for the site build's taxonomy decision |
|
|
345
346
|
| `isDraftNote` | `isDraftNote(fm)` | `boolean` | checking whether a note is tagged as an unfinished draft |
|
|
346
347
|
| `subTypeCharsetMessage` | `subTypeCharsetMessage(value)` | `string` | building the message for a `subType` outside the address charset |
|
|
347
348
|
| `typeCharsetMessage` | `typeCharsetMessage(type)` | `string` | building the message for a `type` outside the address charset |
|
|
@@ -491,21 +492,22 @@ The shortcodes a note declares it used to be published under. A package's `(type
|
|
|
491
492
|
|
|
492
493
|
The published content index — the artifact packages exchange addresses through. **A package publishes its own index; a consumer fetches the ones it depends on.** That is the whole mechanism, and it replaces a vendored link manifest that each repository committed a copy of every other repository's file into. Vendoring failed three ways, and only the last is about staleness:
|
|
493
494
|
|
|
494
|
-
| Export | Signature | Returns | Use it when
|
|
495
|
-
| ------------------------------ | ---------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
496
|
-
| `METADATA_RELATIONSHIP_KINDS` | `const METADATA_RELATIONSHIP_KINDS` | — | The relationship kinds that are dependencies, and therefore citable.
|
|
497
|
-
| `metadataFileName` | `function metadataFileName(pkg)` | {string} The file name, e.g. | What a package's content index is called, wherever it is written or fetched.
|
|
498
|
-
| `metadataRelationships` | `function metadataRelationships(config)` | {Array<{id: string, manifest: string, kind: string, verified: string\|undefined}>} The dependencies, in declaration order. | Every dependency whose published index this build resolves addresses through.
|
|
499
|
-
| `
|
|
500
|
-
| `
|
|
501
|
-
| `
|
|
502
|
-
| `
|
|
503
|
-
| `
|
|
504
|
-
| `
|
|
505
|
-
| `
|
|
506
|
-
| `
|
|
507
|
-
| `
|
|
508
|
-
| `
|
|
495
|
+
| Export | Signature | Returns | Use it when |
|
|
496
|
+
| ------------------------------ | ---------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
|
|
497
|
+
| `METADATA_RELATIONSHIP_KINDS` | `const METADATA_RELATIONSHIP_KINDS` | — | The relationship kinds that are dependencies, and therefore citable. |
|
|
498
|
+
| `metadataFileName` | `function metadataFileName(pkg)` | {string} The file name, e.g. | What a package's content index is called, wherever it is written or fetched. |
|
|
499
|
+
| `metadataRelationships` | `function metadataRelationships(config)` | {Array<{id: string, manifest: string, kind: string, verified: string\|undefined}>} The dependencies, in declaration order. | Every dependency whose published index this build resolves addresses through. |
|
|
500
|
+
| `noContentIndexPackages` | `function noContentIndexPackages(config)` | {ReadonlySet<string>} The content package names. | Every package a relationship declares `contentIndex: false` on, keyed by the content package name a link into it would use. |
|
|
501
|
+
| `metadataCacheDir` | `function metadataCacheDir(config, id, version)` | {string} The directory. | The cache directory for one dependency's index at one version. |
|
|
502
|
+
| `isComplete` | `const isComplete` | {boolean} True when it was fetched to completion. | Whether a dependency's cache is present and complete. |
|
|
503
|
+
| `markComplete` | `function markComplete(dir)` | {void} | Mark a dependency's cache complete. |
|
|
504
|
+
| `cachedMetadataFiles` | `function cachedMetadataFiles(config)` | {string[]} One index file per declared dependency. | The fetched index files this build resolves foreign addresses against. |
|
|
505
|
+
| `cachedMetadataIndexes` | `function cachedMetadataIndexes(config)` | {Array<{id: string, file: string}>} One entry per declared dependency. | The same fetched indexes, each paired with the package that published it. |
|
|
506
|
+
| `newestVersionDir` | `function newestVersionDir(dirs)` | {string} The newest one. | The newest cached version among several version-keyed cache directories. |
|
|
507
|
+
| `loadForeignIndexes` | `function loadForeignIndexes(config, localPackages, bases` | {{index: Map<string, object>, packages: Set<string>, stale: Array<{package: string, reason: string}>}} The resolved addresses, which packages contributed, and what could not be read. | Resolve every foreign address this build can cite, from the fetched indexes. |
|
|
508
|
+
| `cachedIndexPath` | `function cachedIndexPath(config, pkg)` | {string} A path to name in a diagnostic. | Where a dependency's fetched index sits, for naming it in a diagnostic. |
|
|
509
|
+
| `unaddressableForeignPackages` | `function unaddressableForeignPackages(foreignIndex)` | {Array<{package: string, entries: number, sampleKey: string}>} One finding per drifted package, in the order the index first names each. | Whether a fetched index can still be _addressed_, as distinct from read. |
|
|
510
|
+
| `formatUnaddressableFinding` | `function formatUnaddressableFinding(finding, config)` | {string} The formatted diagnostic, path first on the line. | One finding, in the standard `file:line:column: severity: message` form. |
|
|
509
511
|
|
|
510
512
|
### `engine.foundryEntries`
|
|
511
513
|
|
|
@@ -834,14 +836,14 @@ Shared helpers for the pack compilers in `packages/content-build/`. The HeroicLa
|
|
|
834
836
|
|
|
835
837
|
Wikilink resolution for the pack compilers. Content notes link to one another with wikilinks rather than file paths:
|
|
836
838
|
|
|
837
|
-
| Export | Signature | Returns
|
|
838
|
-
| -------------------- | ----------------------------------------------------------------------- |
|
|
839
|
-
| `resolveItemDocType` | `function resolveItemDocType(qualifier, types)` | {string\|null} The underlying document type, or `null` when the qualifier is not a virtual one.
|
|
840
|
-
| `readQualifier` | `function readQualifier(target, types, packages)`
|
|
841
|
-
| `anchorPageId` | `function anchorPageId(noteId, anchorSlug)` | {string} A 16-character alphanumeric id.
|
|
842
|
-
| `buildWikilinkIndex` | `function buildWikilinkIndex(docs, packageId, foreign, contentPackage)` | {{byShortcode: Map<string, object>, types: Set<string>}} `types` is every type the tree actually contains, so a qualifier naming no real type can be told apart from a missing target.
|
|
843
|
-
| `resolveReference` | `function resolveReference(index, ref, hint)` | {{name?: string, uuid?: string, address?: string, subType?: string}\|undefined} The target, or `undefined` where nothing answers.
|
|
844
|
-
| `convertWikilinks` | `function convertWikilinks(markdown,` | {{markdown: string, unresolved: Array<{link: string, target: string, offset: number, reason: string, packages?: string[], anchor?: string}>}} Each `reason` is one of {@link LINK_FINDING_REASONS}, the vocabulary all three resolvers share — `ambiguous` carries the claiming `packages` and `unknown-anchor` the section it named.
|
|
839
|
+
| Export | Signature | Returns | Use it when |
|
|
840
|
+
| -------------------- | ----------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
841
|
+
| `resolveItemDocType` | `function resolveItemDocType(qualifier, types)` | {string\|null} The underlying document type, or `null` when the qualifier is not a virtual one. | Reads a qualifier as the **virtual `doc<type>`** form, or reports that it is not one. |
|
|
842
|
+
| `readQualifier` | `function readQualifier(target, types, packages, noIndexPackages)` | {{type: string, shortcode: string, itemDoc: boolean, package?: string, system?: string, reason?: undefined} \| {reason: "unknown-type"\|"no-content-index", package?: string} \| null} The resolved qualifier; a `reason` when the target is definitely qualified but names no known type or no fetched index; or `null` when it is not an address at all. | Read a link target as a **qualified** `type-shortcode` reference, or report that it does not parse as one. |
|
|
843
|
+
| `anchorPageId` | `function anchorPageId(noteId, anchorSlug)` | {string} A 16-character alphanumeric id. | The deterministic JournalEntryPage id for one anchor: SHA-256 of `"<noteId>-<anchorSlug>"`, base64-encoded, reduced to the 16 alphanumeric characters a Foundry id allows. |
|
|
844
|
+
| `buildWikilinkIndex` | `function buildWikilinkIndex(docs, packageId, foreign, contentPackage)` | {{byShortcode: Map<string, object>, types: Set<string>}} `types` is every type the tree actually contains, so a qualifier naming no real type can be told apart from a missing target. | Builds the link-resolution tables for a content tree. |
|
|
845
|
+
| `resolveReference` | `function resolveReference(index, ref, hint)` | {{name?: string, uuid?: string, address?: string, subType?: string}\|undefined} The target, or `undefined` where nothing answers. | Resolve one reference — a bare shortcode, a short address or a canonical one — to what a compendium can use. |
|
|
846
|
+
| `convertWikilinks` | `function convertWikilinks(markdown,` | {{markdown: string, unresolved: Array<{link: string, target: string, offset: number, reason: string, packages?: string[], anchor?: string}>}} Each `reason` is one of {@link LINK_FINDING_REASONS}, the vocabulary all three resolvers share — `ambiguous` carries the claiming `packages` and `unknown-anchor` the section it named. | Rewrites every wikilink in a markdown body as a Foundry UUID enricher. |
|
|
845
847
|
|
|
846
848
|
### `engine.wikilinkSyntax`
|
|
847
849
|
|
|
@@ -1288,6 +1290,7 @@ console.log(config.stageDir);
|
|
|
1288
1290
|
| `resolvePackageBuildConfig` | `resolvePackageBuildConfig(shared)` | `Readonly<PackageBuildConfig>` | validating the `packageBuild:` section from an already-loaded shared configuration — the pure half, usable without touching disk |
|
|
1289
1291
|
| `loadPackageBuildConfig` | `loadPackageBuildConfig()` | `Readonly<PackageBuildConfig>` | reading and validating the repository's resolved package-build configuration from disk, read fresh on each call rather than cached at import |
|
|
1290
1292
|
| `checkHomepage` | `checkHomepage(homepage, contentPackage)` | `void` | validating a resolved `homepage` against `contentPackage` — called by `content-build site` before the generated `baseURL` is written, not by `resolvePackageBuildConfig` itself |
|
|
1293
|
+
| `fail` | `fail(where, problem)` | `never` | rejecting a configured value from a sibling module, naming the dotted key path it was written under, so the loader can resolve it to a line and column |
|
|
1291
1294
|
|
|
1292
1295
|
## `./prettier`
|
|
1293
1296
|
|
package/docs/commands.md
CHANGED
|
@@ -166,7 +166,7 @@ Publish this package's DataModel field sets as `schema.json`.
|
|
|
166
166
|
**SYNOPSIS**
|
|
167
167
|
|
|
168
168
|
```
|
|
169
|
-
package-build schema
|
|
169
|
+
package-build schema
|
|
170
170
|
```
|
|
171
171
|
|
|
172
172
|
**DESCRIPTION**
|
|
@@ -174,23 +174,20 @@ package-build schema [--check]
|
|
|
174
174
|
Publishes the registries named in `packageBuild.schema` as `schema.json`, read
|
|
175
175
|
by `content-build content-format schema` and, in a consuming package, by
|
|
176
176
|
`content-build lint`'s emitted-versus-declared check. A repository that
|
|
177
|
-
declares no registries has nothing to publish.
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
`
|
|
181
|
-
|
|
177
|
+
declares no registries has nothing to publish. Reads the registries
|
|
178
|
+
`packageBuild.schema` names; writes `build/schema.json`. A release publishes
|
|
179
|
+
it beside the archive and the manifest when `packageBuild.assets` names
|
|
180
|
+
`build/schema.json` (see `package-build release`); a module's
|
|
181
|
+
`content-build deps fetch` keeps the copy from the archive it downloads.
|
|
182
182
|
|
|
183
183
|
**OPTIONS**
|
|
184
184
|
|
|
185
|
-
|
|
186
|
-
| --------- | ------- | ------- | ------------------------------------------------------------------------------ |
|
|
187
|
-
| `--check` | boolean | `false` | Fail when the committed `schema.json` is out of date rather than rewriting it. |
|
|
185
|
+
None.
|
|
188
186
|
|
|
189
187
|
**EXIT STATUS**
|
|
190
188
|
|
|
191
|
-
1
|
|
192
|
-
|
|
193
|
-
`packageBuild.schema` is empty, which logs and publishes nothing.
|
|
189
|
+
1 on any thrown error. Otherwise 0 — including when `packageBuild.schema` is
|
|
190
|
+
empty, which logs and publishes nothing.
|
|
194
191
|
|
|
195
192
|
**EXAMPLES**
|
|
196
193
|
|
|
@@ -202,7 +199,7 @@ package-build: no `packageBuild.schema` declared; nothing to publish.
|
|
|
202
199
|
**SEE ALSO**
|
|
203
200
|
|
|
204
201
|
`content-build content-format schema`, `content-build lint [root]`,
|
|
205
|
-
[Configuration](configuration.md).
|
|
202
|
+
`package-build release`, [Configuration](configuration.md).
|
|
206
203
|
|
|
207
204
|
### `package-build manifest`
|
|
208
205
|
|
|
@@ -670,14 +667,17 @@ package-build release [--no-pdf]
|
|
|
670
667
|
|
|
671
668
|
The artifact name comes from `packageKind` — a system ships as
|
|
672
669
|
`system.json`'s sibling, a module as `module.json`'s — so no repository
|
|
673
|
-
states it a second time.
|
|
674
|
-
(`
|
|
675
|
-
`
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
the
|
|
680
|
-
|
|
670
|
+
states it a second time. It also publishes the content index the manifest
|
|
671
|
+
advertises (`flags.metadataUrl`) and, when the stage carries one,
|
|
672
|
+
`schema.json` — a repository that names `build/schema.json` in
|
|
673
|
+
`packageBuild.assets` gets it released beside the archive; one that does not
|
|
674
|
+
gets none. When the package publishes content (`publish.site: content`), it
|
|
675
|
+
also builds the content-tree book (see `content-build pdf`) and reports it
|
|
676
|
+
alongside the archive; `--no-pdf` skips that step for a release that has a
|
|
677
|
+
tree but does not want the book this time. A book that fails to build is
|
|
678
|
+
reported, never fatal — the archive above is the release regardless. Reads
|
|
679
|
+
the staged package and (for the book) the content tree; writes
|
|
680
|
+
`<artifact>.zip` and, unless skipped, the book, both under `build/dist`.
|
|
681
681
|
|
|
682
682
|
**OPTIONS**
|
|
683
683
|
|
|
@@ -701,7 +701,7 @@ $ package-build release
|
|
|
701
701
|
|
|
702
702
|
**SEE ALSO**
|
|
703
703
|
|
|
704
|
-
`content-build pdf`, [Configuration](configuration.md).
|
|
704
|
+
`content-build pdf`, `package-build schema`, [Configuration](configuration.md).
|
|
705
705
|
|
|
706
706
|
### `package-build deploy <stage>`
|
|
707
707
|
|