@heroiclands/package-build 22.15.0 → 22.16.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 +103 -0
- package/README.md +39 -678
- package/bin/{content-build.mjs → content-commands.mjs} +197 -118
- package/bin/package-build.mjs +303 -42
- package/bin/report.mjs +1 -1
- package/ci/ci-docker.mjs +6 -3
- package/ci/ci-steps.mjs +6 -4
- package/ci/content-format-reference.mjs +106 -0
- package/config.mjs +22 -2
- package/content-config.mjs +74 -134
- package/docs/api.md +294 -234
- package/docs/authoring/assets.md +31 -0
- package/docs/authoring/dates-and-calendars.md +33 -0
- package/docs/authoring/first-note.md +48 -0
- package/docs/authoring/frontmatter.md +40 -0
- package/docs/authoring/links-and-markup.md +137 -0
- package/docs/commands.md +631 -162
- package/docs/configuration.md +176 -140
- package/docs/content-format.md +50 -4229
- package/docs/design.md +32 -0
- package/docs/diagnostics.md +29 -22
- package/docs/getting-started.md +21 -877
- package/docs/guides/book.md +153 -0
- package/docs/guides/e2e.md +143 -0
- package/docs/guides/icons.md +126 -0
- package/docs/guides/localization.md +120 -0
- package/docs/guides/module-project.md +915 -0
- package/docs/guides/packs.md +167 -0
- package/docs/guides/reference-pages.md +148 -0
- package/docs/guides/release-and-deploy.md +114 -0
- package/docs/guides/site.md +152 -0
- package/docs/guides/system-project.md +45 -0
- package/docs/index.md +16 -0
- package/docs/project-setup.md +54 -35
- package/docs/reference/format-details.md +4420 -0
- package/docs/reference/note-types.md +531 -0
- package/engine/address-render.mjs +26 -0
- package/engine/address.mjs +3 -20
- package/engine/anchors.mjs +15 -6
- package/engine/asset-bindings.mjs +6 -2
- package/engine/base-compiler.mjs +47 -11
- package/engine/being-measurements.mjs +70 -0
- package/engine/calendar-artifacts.mjs +1 -1
- package/engine/calendar-choice.mjs +32 -0
- package/engine/calendar-human.mjs +71 -0
- package/engine/calendar-notes.mjs +41 -3
- package/engine/calendars.mjs +8 -1
- package/engine/changelog-lint.mjs +2 -2
- package/engine/code-fences.mjs +23 -97
- package/engine/compile-corpus.mjs +6 -7
- package/engine/content-admonitions.mjs +114 -0
- package/engine/content-captions.mjs +181 -0
- package/engine/content-embeds.mjs +2 -2
- package/engine/content-footnotes.mjs +34 -0
- package/engine/content-format-check.mjs +2 -2
- package/engine/content-format.mjs +127 -73
- package/engine/content-format.yaml +745 -0
- package/engine/content-html.mjs +1 -1
- package/engine/content-icons.mjs +45 -92
- package/engine/content-images.mjs +22 -74
- package/engine/content-index.mjs +12 -3
- package/engine/content-links.mjs +21 -26
- package/engine/content-lint.mjs +1 -5
- package/engine/content-secrets.mjs +3 -1
- package/engine/content-tables.mjs +47 -1257
- package/engine/culture-choice.mjs +32 -0
- package/engine/date-conversion.mjs +47 -0
- package/engine/declaration-check.mjs +87 -0
- package/engine/docs-checks.mjs +140 -0
- package/engine/documentation-links.mjs +31 -0
- package/engine/exported-scene.mjs +1 -1
- package/engine/extension-attributes.mjs +74 -0
- package/engine/field-reference.mjs +1 -1
- package/engine/field-spec.mjs +4 -0
- package/engine/foreign-catalog.mjs +5 -5
- package/engine/format-generated.mjs +15 -0
- package/engine/foundry-entries.mjs +3 -1
- package/engine/frontmatter-lint.mjs +5 -1
- package/engine/frontmatter.mjs +10 -0
- package/engine/generate.mjs +2 -2
- package/engine/helpers.mjs +71 -117
- package/engine/homepage.mjs +2 -3
- package/engine/index-records.mjs +1 -0
- package/engine/index.mjs +18 -3
- package/engine/infobox-registry.mjs +3 -1
- package/engine/infobox.mjs +38 -20
- package/engine/item-compiler.mjs +10 -8
- package/engine/item-docs.mjs +7 -6
- package/engine/itinerary-scenes.mjs +4 -2
- package/engine/journals.mjs +51 -10
- package/engine/macros.mjs +1 -1
- package/engine/map-build.mjs +1 -1
- package/engine/map-dot.mjs +1 -1
- package/engine/map-raster.mjs +4 -2
- package/engine/markdown-expressions.mjs +117 -0
- package/engine/metadata-index.mjs +7 -3
- package/engine/note-addresses.mjs +1 -0
- package/engine/note-dates.mjs +283 -61
- package/engine/note-package.mjs +5 -25
- package/engine/note-state.mjs +6 -2
- package/engine/note-vocabulary.mjs +74 -19
- package/engine/number-words.mjs +75 -0
- package/engine/office-holders.mjs +188 -0
- package/engine/pack-config.mjs +2 -15
- package/engine/pack-router.mjs +24 -5
- package/engine/packages.mjs +3 -2
- package/engine/pathnames.mjs +21 -24
- package/engine/pdf-build.mjs +217 -55
- package/engine/pdf-fonts.mjs +2 -2
- package/engine/pdf-images.mjs +82 -0
- package/engine/pdf-render.mjs +174 -22
- package/engine/populations.mjs +3 -2
- package/engine/project-init.mjs +499 -0
- package/engine/prose-config.mjs +1 -1
- package/engine/prose-lint.mjs +7 -6
- package/engine/readability-lint.mjs +86 -0
- package/engine/reckoning-markers.mjs +205 -93
- package/engine/scenes.mjs +5 -2
- package/engine/schema-check.mjs +3 -3
- package/engine/site-build.mjs +87 -37
- package/engine/site-config.mjs +8 -8
- package/engine/site-index.mjs +4 -0
- package/engine/site-maps.mjs +1 -1
- package/engine/site-preview.mjs +19 -8
- package/engine/social-ties.mjs +5 -1
- package/engine/sql-tables.mjs +92 -22
- package/engine/web-wikilinks.mjs +15 -31
- package/engine/wikilink-syntax.mjs +4 -1
- package/engine/wikilinks.mjs +12 -14
- package/hm3/item-fields.mjs +1 -1
- package/hm3/items.mjs +12 -45
- package/index.mjs +2 -14
- package/manifest.mjs +31 -4
- package/markdownlint-config.mjs +1 -1
- package/package.json +32 -11
- package/prettier-config.mjs +1 -1
- package/sohl/being-info.mjs +3 -145
- package/sohl/index.mjs +1 -1
- package/sohl/infobox.mjs +2 -1
- package/sohl/item-builders.mjs +3 -27
- package/sohl/item-fields.mjs +61 -22
- package/sohl/kb-passes.mjs +2 -2
- package/sohl/note-schemas.mjs +0 -8
- package/stage.mjs +19 -0
- package/types/config.d.mts +12 -3
- package/types/content-config.d.mts +15 -81
- package/types/engine/address-render.d.mts +13 -0
- package/types/engine/address.d.mts +2 -11
- package/types/engine/anchors.d.mts +3 -4
- package/types/engine/asset-bindings.d.mts +9 -2
- package/types/engine/base-compiler.d.mts +1 -2
- package/types/engine/being-measurements.d.mts +16 -0
- package/types/engine/calendar-choice.d.mts +14 -0
- package/types/engine/calendar-human.d.mts +4 -0
- package/types/engine/calendar-notes.d.mts +2 -0
- package/types/engine/calendars.d.mts +5 -3
- package/types/engine/code-fences.d.mts +6 -72
- package/types/engine/compile-corpus.d.mts +1 -3
- package/types/engine/content-admonitions.d.mts +24 -0
- package/types/engine/content-captions.d.mts +45 -0
- package/types/engine/content-footnotes.d.mts +10 -0
- package/types/engine/content-format-check.d.mts +17 -4
- package/types/engine/content-format.d.mts +24 -11
- package/types/engine/content-icons.d.mts +14 -23
- package/types/engine/content-images.d.mts +2 -2
- package/types/engine/content-index.d.mts +9 -2
- package/types/engine/content-links.d.mts +3 -5
- package/types/engine/content-tables.d.mts +11 -140
- package/types/engine/culture-choice.d.mts +14 -0
- package/types/engine/date-conversion.d.mts +4 -0
- package/types/engine/declaration-check.d.mts +24 -0
- package/types/engine/docs-checks.d.mts +28 -0
- package/types/engine/documentation-links.d.mts +7 -0
- package/types/engine/exported-scene.d.mts +6 -2
- package/types/engine/extension-attributes.d.mts +14 -0
- package/types/engine/field-spec.d.mts +9 -0
- package/types/engine/format-generated.d.mts +7 -0
- package/types/engine/frontmatter.d.mts +14 -4
- package/types/engine/generate.d.mts +1 -1
- package/types/engine/helpers.d.mts +37 -92
- package/types/engine/homepage.d.mts +2 -3
- package/types/engine/index.d.mts +5 -0
- package/types/engine/infobox-registry.d.mts +3 -1
- package/types/engine/infobox.d.mts +17 -6
- package/types/engine/item-compiler.d.mts +4 -4
- package/types/engine/item-docs.d.mts +4 -3
- package/types/engine/journals.d.mts +10 -7
- package/types/engine/map-graphviz.d.mts +1 -1
- package/types/engine/markdown-expressions.d.mts +17 -0
- package/types/engine/note-dates.d.mts +47 -1
- package/types/engine/note-package.d.mts +3 -19
- package/types/engine/note-state.d.mts +2 -1
- package/types/engine/note-vocabulary.d.mts +9 -0
- package/types/engine/number-words.d.mts +4 -0
- package/types/engine/office-holders.d.mts +14 -0
- package/types/engine/pack-config.d.mts +1 -1
- package/types/engine/packages.d.mts +3 -2
- package/types/engine/pdf-images.d.mts +38 -0
- package/types/engine/populations.d.mts +2 -2
- package/types/engine/project-init.d.mts +17 -0
- package/types/engine/prose-config.d.mts +1 -1
- package/types/engine/prose-lint.d.mts +3 -2
- package/types/engine/readability-lint.d.mts +22 -0
- package/types/engine/reckoning-markers.d.mts +4 -2
- package/types/engine/schema-check.d.mts +3 -3
- package/types/engine/site-build.d.mts +38 -28
- package/types/engine/site-config.d.mts +2 -2
- package/types/engine/site-index.d.mts +4 -0
- package/types/engine/site-preview.d.mts +1 -1
- package/types/engine/social-ties.d.mts +8 -2
- package/types/engine/sql-tables.d.mts +13 -2
- package/types/engine/web-wikilinks.d.mts +2 -1
- package/types/engine/wikilinks.d.mts +7 -1
- package/types/hm3/items.d.mts +5 -6
- package/types/labels.d.mts +40 -0
- package/types/manifest.d.mts +3 -3
- package/types/sohl/actors.d.mts +2 -2
- package/types/sohl/being-info.d.mts +3 -43
- package/types/sohl/index.d.mts +1 -1
- package/types/sohl/infobox.d.mts +5 -2
- package/types/sohl/item-fields.d.mts +4 -13
- package/types/stage.d.mts +9 -0
- package/CONTENT.md +0 -3239
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
1
|
/*
|
|
3
2
|
* This file is part of the Song of Heroic Lands (SoHL) system for Foundry VTT.
|
|
4
3
|
* Copyright (c) 2024-2026 Tom Rodriguez ("Toasty") — <toasty@heroiclands.org>
|
|
@@ -13,43 +12,26 @@
|
|
|
13
12
|
*/
|
|
14
13
|
|
|
15
14
|
/**
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* effect the pack pipeline has lives here**: argv parsing, `loglevel`
|
|
20
|
-
* configuration, directory creation, reading the shipped Foundry package
|
|
21
|
-
* manifest, and the process exit code. The library itself is import-safe, so a
|
|
22
|
-
* consuming repository's build — or a test — can call it without any of this
|
|
23
|
-
* happening.
|
|
24
|
-
*
|
|
25
|
-
* The side effects that need *configuration* live inside the command handler,
|
|
26
|
-
* not at module scope, so `--version` and `--help` answer in a directory that
|
|
27
|
-
* has neither a `package-build.config.yaml` nor a package manifest.
|
|
28
|
-
* Running an actual command still resolves both, and still fails loudly when
|
|
29
|
-
* either is missing.
|
|
30
|
-
*
|
|
31
|
-
* Every path and pack name it hands the library comes from the consuming
|
|
32
|
-
* repository's `package-build.config.yaml`, located by
|
|
33
|
-
* `engine/pack-config.mjs`; nothing about any one repository's layout is
|
|
34
|
-
* written here.
|
|
15
|
+
* Content command modules registered by the `package-build` CLI.
|
|
16
|
+
* Configuration is read in handlers, so help and version work without a
|
|
17
|
+
* package configuration. Build inputs come from `package-build.config.yaml`.
|
|
35
18
|
*
|
|
36
19
|
* Usage:
|
|
37
|
-
* npx
|
|
38
|
-
* npx
|
|
39
|
-
* npx
|
|
40
|
-
* npx
|
|
41
|
-
* npx
|
|
42
|
-
* npx
|
|
43
|
-
* npx
|
|
44
|
-
* npx
|
|
45
|
-
* npx
|
|
46
|
-
* npx
|
|
47
|
-
* npx
|
|
48
|
-
* npx
|
|
49
|
-
* npx
|
|
50
|
-
* npx
|
|
51
|
-
* npx
|
|
52
|
-
* npx content-build addresses diff --from <zip|dir> [--strict]
|
|
20
|
+
* npx package-build package compile [pack]
|
|
21
|
+
* npx package-build package unpack [pack] [entry]
|
|
22
|
+
* npx package-build package clean [pack] [entry]
|
|
23
|
+
* npx package-build docs item-fields [--out <path>] [--title <title>]
|
|
24
|
+
* npx package-build lint [root] [--no-references]
|
|
25
|
+
* npx package-build content-format schema --schema <system>=<path>
|
|
26
|
+
* npx package-build content-format fields [--fields <system>]
|
|
27
|
+
* npx package-build content-format notes [root] [--strict]
|
|
28
|
+
* npx package-build links [root] [--manifests <dir>]
|
|
29
|
+
* npx package-build format [paths..] [--write]
|
|
30
|
+
* npx package-build markdown [paths..] [--fix]
|
|
31
|
+
* npx package-build site [--out <dir>]
|
|
32
|
+
* npx package-build map [--tree] [--from <shortcode>] [--chart <shortcode>] [--travel] [--out <dir>]
|
|
33
|
+
* npx package-build reachability <dir> [file] [--index <shortcode>]
|
|
34
|
+
* npx package-build addresses diff --from <zip|dir> [--strict]
|
|
53
35
|
*
|
|
54
36
|
* In a consuming repository, wrapped as npm scripts — SoHL spells them:
|
|
55
37
|
* npm run build:compiledb // → … package compile (all packs)
|
|
@@ -61,11 +43,9 @@ import fs from "fs";
|
|
|
61
43
|
import path from "node:path";
|
|
62
44
|
import log from "loglevel";
|
|
63
45
|
import prefix from "loglevel-plugin-prefix";
|
|
64
|
-
import yargs from "yargs";
|
|
65
|
-
import { hideBin } from "yargs/helpers";
|
|
66
46
|
import { compilePacks, cleanPacks, unpackPacks } from "../engine/compendiums.mjs";
|
|
67
|
-
import { compilesFoundryDocuments } from "../content-config.mjs";
|
|
68
|
-
import { loadPackConfig } from "../engine/pack-config.mjs";
|
|
47
|
+
import { compilesFoundryDocuments, publishesContentPages } from "../content-config.mjs";
|
|
48
|
+
import { loadPackConfig, packConfigPath } from "../engine/pack-config.mjs";
|
|
69
49
|
import { buildPdf } from "../engine/pdf-build.mjs";
|
|
70
50
|
import {
|
|
71
51
|
fetchAllCatalogs,
|
|
@@ -76,12 +56,14 @@ import {
|
|
|
76
56
|
} from "../engine/foreign-catalog.mjs";
|
|
77
57
|
import {
|
|
78
58
|
metadataRelationships,
|
|
59
|
+
cachedMetadataIndexes,
|
|
79
60
|
cachedIndexPath,
|
|
80
61
|
unaddressableForeignPackages,
|
|
81
62
|
formatUnaddressableFinding,
|
|
82
63
|
} from "../engine/metadata-index.mjs";
|
|
83
64
|
import { fetchNavigation, generateHugoConfig, writeHugoConfig } from "../engine/site-config.mjs";
|
|
84
65
|
import { renderItemFieldReference, renderItemFieldsPage } from "../engine/field-reference.mjs";
|
|
66
|
+
import { checkDocLinks, checkDocIndex } from "../engine/docs-checks.mjs";
|
|
85
67
|
import { lintContentTree } from "../engine/content-lint.mjs";
|
|
86
68
|
import { lintNoteStates } from "../engine/stub-lint.mjs";
|
|
87
69
|
import { lintContentCharset } from "../engine/content-charset.mjs";
|
|
@@ -115,6 +97,8 @@ import { ENGINE_NOTE_SCHEMAS } from "../engine/note-schemas.mjs";
|
|
|
115
97
|
import { schemaSubtypeOf } from "../engine/subtype-registry.mjs";
|
|
116
98
|
import { NOTE_VOCABULARY } from "../engine/note-vocabulary.mjs";
|
|
117
99
|
import { checkFormatting, checkPrettierConventions, lintMarkdown } from "../engine/prose-lint.mjs";
|
|
100
|
+
import { lintProse } from "../engine/readability-lint.mjs";
|
|
101
|
+
import { loadPackageBuildConfig } from "../config.mjs";
|
|
118
102
|
import {
|
|
119
103
|
authoredFrontmatter,
|
|
120
104
|
emitContentIndex,
|
|
@@ -170,21 +154,6 @@ function configuredPacks() {
|
|
|
170
154
|
return loadPackConfig().packDirectories.map((name) => ({ name }));
|
|
171
155
|
}
|
|
172
156
|
|
|
173
|
-
/**
|
|
174
|
-
* This package's own version, for `--version`.
|
|
175
|
-
*
|
|
176
|
-
* Read from the package's `package.json` rather than left to yargs, which
|
|
177
|
-
* defaults to the *nearest* `package.json` walking up from the working
|
|
178
|
-
* directory — inside a consuming repository that is the consumer's manifest, so
|
|
179
|
-
* `content-build --version` reported the consumer's version instead of the
|
|
180
|
-
* toolchain's.
|
|
181
|
-
*
|
|
182
|
-
* @returns {string} The `version` field of this package's manifest.
|
|
183
|
-
*/
|
|
184
|
-
function ownVersion() {
|
|
185
|
-
return JSON.parse(fs.readFileSync(new URL("../package.json", import.meta.url), "utf8")).version;
|
|
186
|
-
}
|
|
187
|
-
|
|
188
157
|
// Configure loglevel
|
|
189
158
|
log.setLevel("info"); // Set desired logging level
|
|
190
159
|
|
|
@@ -246,33 +215,109 @@ function readRawNote(file) {
|
|
|
246
215
|
*/
|
|
247
216
|
const SHIPPED_ITEM_FIELDS = { sohl: ITEM_FIELDS, hm3: HM3_ITEM_FIELDS };
|
|
248
217
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
218
|
+
/** Register the content operations on the package command line. */
|
|
219
|
+
export function registerContentCommands(cli) {
|
|
220
|
+
return cli
|
|
221
|
+
.command(withIndexPreflight(packageCommand(), (_config, argv) => argv.action === "compile"))
|
|
222
|
+
.command(depsCommand())
|
|
223
|
+
.command(docsCommand())
|
|
224
|
+
.command(withIndexPreflight(lintCommand()))
|
|
225
|
+
.command(proseCommand())
|
|
226
|
+
.command(contentFormatCommand())
|
|
227
|
+
.command(withIndexPreflight(linksCommand()))
|
|
228
|
+
.command(formatCommand())
|
|
229
|
+
.command(markdownCommand())
|
|
230
|
+
.command(contentIndexCommand())
|
|
231
|
+
.command(withIndexPreflight(siteCommand(), publishesContentPages))
|
|
232
|
+
.command(
|
|
233
|
+
withIndexPreflight(
|
|
234
|
+
pdfCommand(),
|
|
235
|
+
(config) => config.pdf && publishesContentPages(config),
|
|
236
|
+
),
|
|
237
|
+
)
|
|
238
|
+
.command(withIndexPreflight(mapCommand()))
|
|
239
|
+
.command(withIndexPreflight(reachabilityCommand()))
|
|
240
|
+
.command(addressesCommand());
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/** Opt-in readability and plain-language suggestions for Markdown notes. */
|
|
244
|
+
function proseCommand() {
|
|
245
|
+
return {
|
|
246
|
+
command: "prose <action> [path]",
|
|
247
|
+
describe: "Analyze note prose on demand",
|
|
248
|
+
builder: (yargs) =>
|
|
249
|
+
yargs
|
|
250
|
+
.positional("action", { choices: ["lint"], describe: "Analyze prose" })
|
|
251
|
+
.positional("path", {
|
|
252
|
+
type: "string",
|
|
253
|
+
describe: "One Markdown file or a content tree",
|
|
254
|
+
})
|
|
255
|
+
.option("age", { type: "number", describe: "Reader age" })
|
|
256
|
+
.option("threshold", {
|
|
257
|
+
type: "number",
|
|
258
|
+
describe: "Readability algorithms required (1–7)",
|
|
259
|
+
})
|
|
260
|
+
.option("min-words", { type: "number", describe: "Minimum words per sentence" }),
|
|
261
|
+
handler: async (argv) => {
|
|
262
|
+
try {
|
|
263
|
+
const config = loadPackConfig();
|
|
264
|
+
const defaults = loadPackageBuildConfig().proseLint;
|
|
265
|
+
const options = {
|
|
266
|
+
age: argv.age ?? defaults.age,
|
|
267
|
+
threshold: argv.threshold ?? defaults.threshold,
|
|
268
|
+
minWords: argv.minWords ?? defaults.minWords,
|
|
269
|
+
};
|
|
270
|
+
for (const [key, value] of Object.entries(options)) {
|
|
271
|
+
if (
|
|
272
|
+
!Number.isInteger(value) ||
|
|
273
|
+
value < 1 ||
|
|
274
|
+
(key === "threshold" && value > 7)
|
|
275
|
+
) {
|
|
276
|
+
throw new TypeError(
|
|
277
|
+
`${key} must be ${key === "threshold" ? "an integer from 1 to 7" : "a positive integer"}`,
|
|
278
|
+
);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
const findings = await lintProse(
|
|
282
|
+
argv.path ?? config.paths.content,
|
|
283
|
+
options,
|
|
284
|
+
config.skipDirectories,
|
|
285
|
+
);
|
|
286
|
+
for (const finding of findings) emitDiagnostic(finding);
|
|
287
|
+
log.info(`${findings.length} prose suggestion(s).`);
|
|
288
|
+
} catch (err) {
|
|
289
|
+
reportFailure(err);
|
|
290
|
+
process.exitCode = 1;
|
|
291
|
+
}
|
|
292
|
+
},
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/** Check declared dependency indexes before an index-consuming command does any work. */
|
|
297
|
+
function withIndexPreflight(command, shouldCheck = () => true) {
|
|
298
|
+
const handler = command.handler;
|
|
299
|
+
return {
|
|
300
|
+
...command,
|
|
301
|
+
handler: async (argv) => {
|
|
302
|
+
let config;
|
|
303
|
+
try {
|
|
304
|
+
config = loadPackConfig();
|
|
305
|
+
if (shouldCheck(config, argv)) cachedMetadataIndexes(config);
|
|
306
|
+
} catch (err) {
|
|
307
|
+
if (config) {
|
|
308
|
+
emitDiagnostic({
|
|
309
|
+
file: packConfigPath(),
|
|
310
|
+
severity: "error",
|
|
311
|
+
message: err instanceof Error ? err.message : String(err),
|
|
312
|
+
});
|
|
313
|
+
} else reportFailure(err);
|
|
314
|
+
process.exitCode = 1;
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
return handler(argv);
|
|
318
|
+
},
|
|
319
|
+
};
|
|
320
|
+
}
|
|
276
321
|
|
|
277
322
|
/**
|
|
278
323
|
* `docs item-fields` — render this repository's item-frontmatter reference.
|
|
@@ -309,16 +354,21 @@ const argv = yargs(hideBin(process.argv))
|
|
|
309
354
|
function docsCommand() {
|
|
310
355
|
return {
|
|
311
356
|
command: "docs <action>",
|
|
312
|
-
describe: "Generate
|
|
357
|
+
describe: "Generate and check project documentation",
|
|
313
358
|
builder: (yargs) => {
|
|
314
359
|
// Required and honoured, not optional and unread:
|
|
315
360
|
// the handler rendered the item-field reference whatever it was
|
|
316
361
|
// given, so the positional constrained what could be typed and
|
|
317
362
|
// selected nothing.
|
|
318
363
|
yargs.positional("action", {
|
|
319
|
-
describe: "The
|
|
364
|
+
describe: "The documentation action.",
|
|
320
365
|
type: "string",
|
|
321
|
-
choices: ["item-fields"],
|
|
366
|
+
choices: ["item-fields", "links", "index"],
|
|
367
|
+
});
|
|
368
|
+
yargs.option("root", {
|
|
369
|
+
describe: "Documentation root for the links and index checks.",
|
|
370
|
+
type: "string",
|
|
371
|
+
default: "docs",
|
|
322
372
|
});
|
|
323
373
|
yargs.option("out", {
|
|
324
374
|
describe: "Write to this file instead of the configured location.",
|
|
@@ -337,6 +387,26 @@ function docsCommand() {
|
|
|
337
387
|
handler: (argv) => {
|
|
338
388
|
try {
|
|
339
389
|
const { action, title, check } = argv;
|
|
390
|
+
if (action === "links" || action === "index") {
|
|
391
|
+
const requestedRoot = path.resolve(argv.root);
|
|
392
|
+
const root =
|
|
393
|
+
fs.existsSync(requestedRoot) ?
|
|
394
|
+
fs.realpathSync(requestedRoot)
|
|
395
|
+
: requestedRoot;
|
|
396
|
+
const findings = action === "links" ? checkDocLinks(root) : checkDocIndex(root);
|
|
397
|
+
for (const finding of findings) {
|
|
398
|
+
emitDiagnostic({
|
|
399
|
+
...finding,
|
|
400
|
+
file: path.relative(process.cwd(), finding.file),
|
|
401
|
+
});
|
|
402
|
+
}
|
|
403
|
+
if (findings.length) process.exitCode = 1;
|
|
404
|
+
else
|
|
405
|
+
log.info(
|
|
406
|
+
`Documentation ${action} check passed for ${path.relative(process.cwd(), root) || "."}.`,
|
|
407
|
+
);
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
340
410
|
// Dispatched on, so a second document added here cannot
|
|
341
411
|
// silently render the first. yargs' `choices` has already
|
|
342
412
|
// rejected anything unlisted, so the default is unreachable by
|
|
@@ -354,7 +424,7 @@ function docsCommand() {
|
|
|
354
424
|
const body = `${renderItemFieldReference({
|
|
355
425
|
title: pageTitle,
|
|
356
426
|
...(spec.preamble ? { preamble: spec.preamble } : {}),
|
|
357
|
-
generatedBy: "`
|
|
427
|
+
generatedBy: "`package-build docs item-fields`",
|
|
358
428
|
config,
|
|
359
429
|
})}\n`;
|
|
360
430
|
// A page filed under the content tree is walked for its
|
|
@@ -395,7 +465,7 @@ function docsCommand() {
|
|
|
395
465
|
severity: "error",
|
|
396
466
|
message:
|
|
397
467
|
"out of date with the item-field declarations " +
|
|
398
|
-
"— run `
|
|
468
|
+
"— run `package-build docs item-fields` and " +
|
|
399
469
|
"commit the regenerated file",
|
|
400
470
|
});
|
|
401
471
|
process.exitCode = 1;
|
|
@@ -423,7 +493,7 @@ function docsCommand() {
|
|
|
423
493
|
}
|
|
424
494
|
|
|
425
495
|
/**
|
|
426
|
-
* `
|
|
496
|
+
* `package-build content-format` — check the format specification itself.
|
|
427
497
|
*
|
|
428
498
|
* Two checks, because the specification makes claims about two different
|
|
429
499
|
* worlds, and they fail for different reasons and at different times:
|
|
@@ -431,15 +501,11 @@ function docsCommand() {
|
|
|
431
501
|
* - `schema` compares every `system.*` target the document names against the
|
|
432
502
|
* naming system's published `schema.json`. A failure means the specification
|
|
433
503
|
* and the system disagree, which is a defect in one of the two.
|
|
434
|
-
* - `fields` compares
|
|
435
|
-
*
|
|
436
|
-
* - `notes` measures a content tree against the vocabulary the document
|
|
437
|
-
* declares per type. During the migration it is the progress bar rather
|
|
438
|
-
* than a gate, so it **reports** by default and `--strict` makes it fatal —
|
|
439
|
-
* turned on one class at a time as each slice lands.
|
|
504
|
+
* - `fields` compares declared field mappings with compiler declarations.
|
|
505
|
+
* - `notes` measures authored notes against the declared vocabulary.
|
|
440
506
|
*
|
|
441
|
-
*
|
|
442
|
-
*
|
|
507
|
+
* The shipped contract is `engine/content-format.yaml`; guide layout does not
|
|
508
|
+
* participate in validation.
|
|
443
509
|
*
|
|
444
510
|
* @returns {object} The yargs command module.
|
|
445
511
|
*/
|
|
@@ -489,7 +555,7 @@ function contentFormatSchemaCommand() {
|
|
|
489
555
|
builder: (yargs) => {
|
|
490
556
|
yargs.option("spec", {
|
|
491
557
|
describe:
|
|
492
|
-
"The
|
|
558
|
+
"The format contract to read. Defaults to the engine/content-format.yaml this package ships.",
|
|
493
559
|
type: "string",
|
|
494
560
|
});
|
|
495
561
|
yargs.option("schema", {
|
|
@@ -597,7 +663,7 @@ function contentFormatFieldsCommand() {
|
|
|
597
663
|
builder: (yargs) => {
|
|
598
664
|
yargs.option("spec", {
|
|
599
665
|
describe:
|
|
600
|
-
"The
|
|
666
|
+
"The format contract to read. Defaults to the engine/content-format.yaml this package ships.",
|
|
601
667
|
type: "string",
|
|
602
668
|
});
|
|
603
669
|
yargs.option("fields", {
|
|
@@ -686,7 +752,7 @@ function contentFormatNotesCommand() {
|
|
|
686
752
|
});
|
|
687
753
|
yargs.option("spec", {
|
|
688
754
|
describe:
|
|
689
|
-
"The
|
|
755
|
+
"The format contract to read. Defaults to the engine/content-format.yaml this package ships.",
|
|
690
756
|
type: "string",
|
|
691
757
|
});
|
|
692
758
|
yargs.option("strict", {
|
|
@@ -754,7 +820,7 @@ function contentFormatNotesCommand() {
|
|
|
754
820
|
}
|
|
755
821
|
|
|
756
822
|
/**
|
|
757
|
-
* `
|
|
823
|
+
* `package-build lint` — check a content tree's addresses.
|
|
758
824
|
*
|
|
759
825
|
* Deliberately independent of the pack pipeline: it compiles nothing, opens no
|
|
760
826
|
* LevelDB and needs no Foundry manifest, so it runs in a second and can gate a
|
|
@@ -910,7 +976,7 @@ function lintCommand() {
|
|
|
910
976
|
`@${config.stats.systemVersion ?? "?"}, so emitted ` +
|
|
911
977
|
`\`system\` fields are unchecked. A system ` +
|
|
912
978
|
`generates its own; a module gets one from ` +
|
|
913
|
-
`\`
|
|
979
|
+
`\`package-build deps fetch\`.`,
|
|
914
980
|
);
|
|
915
981
|
}
|
|
916
982
|
const fieldSpecs = config.itemFields ?? {};
|
|
@@ -1061,7 +1127,7 @@ function lintCommand() {
|
|
|
1061
1127
|
}
|
|
1062
1128
|
|
|
1063
1129
|
/**
|
|
1064
|
-
* `
|
|
1130
|
+
* `package-build format` — Prettier, with the shared configuration.
|
|
1065
1131
|
*
|
|
1066
1132
|
* Deliberately **not** scoped to the content tree, and deliberately free of the
|
|
1067
1133
|
* pack configuration: a repository's formatting covers everything it holds, and
|
|
@@ -1167,7 +1233,7 @@ function formatCommand() {
|
|
|
1167
1233
|
}
|
|
1168
1234
|
|
|
1169
1235
|
/**
|
|
1170
|
-
* `
|
|
1236
|
+
* `package-build markdown` — markdownlint, with the shared rule set.
|
|
1171
1237
|
*
|
|
1172
1238
|
* The structural checks Prettier cannot make: a heading level that skips, two
|
|
1173
1239
|
* sibling headings claiming one anchor, a reversed link, an emphasis marker
|
|
@@ -1215,7 +1281,7 @@ function markdownCommand() {
|
|
|
1215
1281
|
}
|
|
1216
1282
|
|
|
1217
1283
|
/**
|
|
1218
|
-
* `
|
|
1284
|
+
* `package-build links` — check that every link in a content tree lands.
|
|
1219
1285
|
*
|
|
1220
1286
|
* Reports a dead `#anchor`, a dead qualified address, and a wikilink authored
|
|
1221
1287
|
* in frontmatter, plus a vendored manifest that has drifted out of reach. All
|
|
@@ -1278,7 +1344,7 @@ function linksCommand() {
|
|
|
1278
1344
|
message: `unusable content index: ${s.reason}`,
|
|
1279
1345
|
});
|
|
1280
1346
|
}
|
|
1281
|
-
log.error("Re-run `
|
|
1347
|
+
log.error("Re-run `package-build deps fetch`.");
|
|
1282
1348
|
process.exitCode = 1;
|
|
1283
1349
|
return;
|
|
1284
1350
|
}
|
|
@@ -1385,7 +1451,7 @@ function linksCommand() {
|
|
|
1385
1451
|
}
|
|
1386
1452
|
|
|
1387
1453
|
/**
|
|
1388
|
-
* `
|
|
1454
|
+
* `package-build content-index` — emit this package's note index.
|
|
1389
1455
|
*
|
|
1390
1456
|
* Every build already walks the tree and parses every note's frontmatter, then
|
|
1391
1457
|
* throws the result away, so nothing outside a build can ask a question about
|
|
@@ -1438,7 +1504,7 @@ function contentIndexCommand() {
|
|
|
1438
1504
|
}
|
|
1439
1505
|
|
|
1440
1506
|
/**
|
|
1441
|
-
* `
|
|
1507
|
+
* `package-build pdf` — build the book the content tree publishes as.
|
|
1442
1508
|
*
|
|
1443
1509
|
* The third surface, beside `package compile` and `site`. It takes the same
|
|
1444
1510
|
* `--out` override the site command does, and reports what it found in the same
|
|
@@ -1490,6 +1556,9 @@ function pdfCommand() {
|
|
|
1490
1556
|
// resolve is an error, because the same statement is wrong in
|
|
1491
1557
|
// Foundry and on the website too.
|
|
1492
1558
|
const errors = reportFindings(result.findings, {});
|
|
1559
|
+
for (const report of result.imageReports ?? []) {
|
|
1560
|
+
log.info(`${report.file}: ${report.message}`);
|
|
1561
|
+
}
|
|
1493
1562
|
|
|
1494
1563
|
if (!result.built) {
|
|
1495
1564
|
// A reason is a deliberate no-op — the fence, an absent
|
|
@@ -1523,7 +1592,7 @@ function pdfCommand() {
|
|
|
1523
1592
|
}
|
|
1524
1593
|
|
|
1525
1594
|
/**
|
|
1526
|
-
* `
|
|
1595
|
+
* `package-build site` — publish the content tree as a website.
|
|
1527
1596
|
*
|
|
1528
1597
|
* The sibling of `package compile`: the same tree, rendered as pages instead of
|
|
1529
1598
|
* compiled into packs. Everything a consumer would otherwise write for itself —
|
|
@@ -1567,6 +1636,8 @@ function siteCommand() {
|
|
|
1567
1636
|
config,
|
|
1568
1637
|
sqlTables: await prepareTreeSqlTables(config.paths.content, {
|
|
1569
1638
|
skipDirectories: config.skipDirectories,
|
|
1639
|
+
config,
|
|
1640
|
+
audience: "public",
|
|
1570
1641
|
}),
|
|
1571
1642
|
});
|
|
1572
1643
|
const { gates } = result;
|
|
@@ -1627,9 +1698,15 @@ function siteCommand() {
|
|
|
1627
1698
|
message: e.reason,
|
|
1628
1699
|
});
|
|
1629
1700
|
}
|
|
1701
|
+
for (const e of result.expressionErrors) {
|
|
1702
|
+
emitDiagnostic(e);
|
|
1703
|
+
}
|
|
1630
1704
|
for (const e of result.secretErrors) {
|
|
1631
1705
|
emitDiagnostic({ ...e, severity: "error" });
|
|
1632
1706
|
}
|
|
1707
|
+
for (const e of result.captionErrors) {
|
|
1708
|
+
emitDiagnostic({ ...e, severity: "error" });
|
|
1709
|
+
}
|
|
1633
1710
|
// Reported the way the pack build reports the very same
|
|
1634
1711
|
// finding: `file:line:column: error: message`, path first, and
|
|
1635
1712
|
// the message from the shared table, not a
|
|
@@ -1666,7 +1743,9 @@ function siteCommand() {
|
|
|
1666
1743
|
}
|
|
1667
1744
|
if (
|
|
1668
1745
|
result.tableErrors.length ||
|
|
1746
|
+
result.expressionErrors.length ||
|
|
1669
1747
|
result.secretErrors.length ||
|
|
1748
|
+
result.captionErrors.length ||
|
|
1670
1749
|
result.wikiErrors.length ||
|
|
1671
1750
|
result.imageErrors.length
|
|
1672
1751
|
) {
|
|
@@ -1695,7 +1774,7 @@ function siteCommand() {
|
|
|
1695
1774
|
}
|
|
1696
1775
|
|
|
1697
1776
|
/**
|
|
1698
|
-
* `
|
|
1777
|
+
* `package-build map` — draw what the place notes state.
|
|
1699
1778
|
*
|
|
1700
1779
|
* Reads the content index — this package's and every declared dependency's —
|
|
1701
1780
|
* so a consumer's map draws its dependencies' places beside its own, and
|
|
@@ -1814,7 +1893,7 @@ function mapCommand() {
|
|
|
1814
1893
|
});
|
|
1815
1894
|
}
|
|
1816
1895
|
if (world.stale.length) {
|
|
1817
|
-
log.error("Re-run `
|
|
1896
|
+
log.error("Re-run `package-build deps fetch`.");
|
|
1818
1897
|
process.exitCode = 1;
|
|
1819
1898
|
return;
|
|
1820
1899
|
}
|
|
@@ -1851,14 +1930,14 @@ function mapCommand() {
|
|
|
1851
1930
|
}
|
|
1852
1931
|
|
|
1853
1932
|
/**
|
|
1854
|
-
* `
|
|
1933
|
+
* `package-build reachability <dir> [file]` — check that a corpus reads through.
|
|
1855
1934
|
*
|
|
1856
1935
|
* The corpus is named on the command line rather than declared in code, because
|
|
1857
1936
|
* it never changes for a given repository: a consumer hardcodes the invocation
|
|
1858
1937
|
* in `package.json` and gets the check without writing a script.
|
|
1859
1938
|
*
|
|
1860
|
-
*
|
|
1861
|
-
*
|
|
1939
|
+
* package-build reachability Rules --index glossary
|
|
1940
|
+
* package-build reachability User_Guide --index glossary
|
|
1862
1941
|
*
|
|
1863
1942
|
* @returns {object} The yargs command module.
|
|
1864
1943
|
*/
|
|
@@ -2118,7 +2197,7 @@ function depsCommand() {
|
|
|
2118
2197
|
*
|
|
2119
2198
|
* ```sh
|
|
2120
2199
|
* gh release download v0.8.2 -p system.zip -D build/baseline
|
|
2121
|
-
* npx
|
|
2200
|
+
* npx package-build addresses diff --from build/baseline/system.zip
|
|
2122
2201
|
* ```
|
|
2123
2202
|
*
|
|
2124
2203
|
* @param {object} config - The resolved build configuration.
|
|
@@ -2261,10 +2340,10 @@ function addressesCommand() {
|
|
|
2261
2340
|
function packageCommand() {
|
|
2262
2341
|
return {
|
|
2263
2342
|
command: "package <action> [pack] [entry]",
|
|
2264
|
-
describe: "
|
|
2343
|
+
describe: "Compile, unpack, or clean compendium packs",
|
|
2265
2344
|
builder: (yargs) => {
|
|
2266
2345
|
// Required, not optional: the action *is* the work, and an
|
|
2267
|
-
// optional one meant `
|
|
2346
|
+
// optional one meant `package-build package` fell through the
|
|
2268
2347
|
// switch below and exited 0 having compiled nothing.
|
|
2269
2348
|
yargs.positional("action", {
|
|
2270
2349
|
describe: "The action to perform.",
|
|
@@ -2296,8 +2375,8 @@ function packageCommand() {
|
|
|
2296
2375
|
throw new Error(
|
|
2297
2376
|
`\`packageKind: ${config.packageKind}\` compiles no ` +
|
|
2298
2377
|
`compendium, so there is nothing to ${action}. Build ` +
|
|
2299
|
-
`its site with \`
|
|
2300
|
-
`with \`
|
|
2378
|
+
`its site with \`package-build site\` and its book ` +
|
|
2379
|
+
`with \`package-build pdf\`.`,
|
|
2301
2380
|
);
|
|
2302
2381
|
}
|
|
2303
2382
|
// The one directory the pipeline creates rather than expects:
|