@heroiclands/package-build 20.3.0 → 20.4.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 +97 -0
- package/CONTENT.md +111 -92
- package/README.md +2 -9
- package/bin/content-build.mjs +70 -61
- package/bin/package-build.mjs +2 -2
- package/config.mjs +6 -8
- package/content-config.mjs +187 -64
- package/docs/content-format.md +57 -68
- package/e2e.mjs +4 -4
- package/engine/actor-compiler.mjs +36 -36
- package/engine/address-charset.mjs +6 -6
- package/engine/address-diff.mjs +12 -11
- package/engine/anchored-sections.mjs +1 -1
- package/engine/anchors.mjs +1 -1
- package/engine/base-compiler.mjs +36 -38
- package/engine/bundle-notes.mjs +4 -4
- package/engine/bundles.mjs +8 -8
- package/engine/code-fences.mjs +3 -3
- package/engine/compendiums.mjs +8 -8
- package/engine/compile-corpus.mjs +4 -5
- package/engine/content-address.mjs +15 -15
- package/engine/content-charset.mjs +1 -1
- package/engine/content-format-check.mjs +24 -25
- package/engine/content-format.mjs +8 -8
- package/engine/content-html.mjs +202 -0
- package/engine/content-icons.mjs +225 -98
- package/engine/content-index.mjs +17 -17
- package/engine/content-links.mjs +30 -30
- package/engine/content-lint.mjs +20 -24
- package/engine/content-package.mjs +7 -9
- package/engine/content-slug.mjs +2 -2
- package/engine/content-tables.mjs +7 -8
- package/engine/content-tree.mjs +1 -1
- package/engine/derived-fields.mjs +174 -0
- package/engine/diagnostics.mjs +3 -4
- package/engine/document-subtypes.mjs +6 -7
- package/engine/field-reference.mjs +8 -8
- package/engine/field-spec.mjs +29 -30
- package/engine/folder-notes.mjs +14 -14
- package/engine/foreign-catalog.mjs +8 -9
- package/engine/foundry-entries.mjs +19 -20
- package/engine/frontmatter-lint.mjs +64 -69
- package/engine/frontmatter.mjs +11 -11
- package/engine/generate.mjs +39 -39
- package/engine/helpers.mjs +63 -54
- package/engine/homepage.mjs +20 -22
- package/engine/ids.mjs +15 -15
- package/engine/index-records.mjs +4 -4
- package/engine/index.mjs +14 -8
- package/engine/item-compiler.mjs +54 -29
- package/engine/item-docs.mjs +11 -13
- package/engine/item-registry.mjs +13 -13
- package/engine/journals.mjs +15 -15
- package/engine/macros.mjs +3 -3
- package/engine/map-notes.mjs +6 -6
- package/engine/metadata-index.mjs +5 -5
- package/engine/note-claims.mjs +36 -34
- package/engine/note-ids.mjs +5 -5
- package/engine/note-package.mjs +4 -4
- package/engine/note-renames.mjs +3 -3
- package/engine/note-schemas.mjs +3 -3
- package/engine/note-vocabulary.mjs +27 -26
- package/engine/pack-config.mjs +13 -13
- package/engine/pack-router.mjs +0 -0
- package/engine/prose-config.mjs +9 -9
- package/engine/prose-lint.mjs +12 -13
- package/engine/region-events.mjs +2 -2
- package/engine/retired-fields.mjs +24 -22
- package/engine/runtime-only-fields.mjs +1 -1
- package/engine/scene-levels.mjs +1 -1
- package/engine/scenes.mjs +19 -20
- package/engine/schema-check.mjs +20 -20
- package/engine/schema-extract.mjs +1 -1
- package/engine/site-build.mjs +45 -47
- package/engine/site-index.mjs +17 -18
- package/engine/sql-tables.mjs +21 -13
- package/engine/subtype-registry.mjs +5 -4
- package/engine/system-block.mjs +18 -19
- package/engine/systems.mjs +2 -2
- package/engine/web-wikilinks.mjs +35 -35
- package/engine/wikilink-syntax.mjs +16 -16
- package/engine/wikilinks.mjs +39 -39
- package/hm3/actors.mjs +22 -22
- package/hm3/document-subtypes.mjs +5 -5
- package/hm3/index.mjs +2 -2
- package/hm3/item-builders.mjs +1 -1
- package/hm3/item-fields.mjs +3 -3
- package/hm3/items.mjs +20 -8
- package/hm3/template-priority.mjs +2 -2
- package/lang.mjs +3 -3
- package/manifest.mjs +17 -20
- package/package.json +1 -2
- package/release.mjs +3 -3
- package/sohl/actors.mjs +28 -28
- package/sohl/affiliation-standings.mjs +2 -2
- package/sohl/being-info.mjs +5 -5
- package/sohl/default-item-art.mjs +5 -5
- package/sohl/document-subtypes.mjs +5 -5
- package/sohl/index.mjs +3 -3
- package/sohl/item-builders.mjs +7 -7
- package/sohl/item-fields.mjs +8 -9
- package/sohl/items.mjs +20 -6
- package/sohl/kb-passes.mjs +5 -5
- package/sohl/note-schemas.mjs +7 -7
- package/sohl/skill-base.mjs +1 -1
- package/types/content-config.d.mts +25 -24
- package/types/e2e.d.mts +3 -3
- package/types/engine/actor-compiler.d.mts +14 -13
- package/types/engine/address-charset.d.mts +6 -6
- package/types/engine/address-diff.d.mts +3 -3
- package/types/engine/base-compiler.d.mts +17 -19
- package/types/engine/bundle-notes.d.mts +3 -3
- package/types/engine/bundles.d.mts +1 -1
- package/types/engine/code-fences.d.mts +3 -3
- package/types/engine/compendiums.d.mts +3 -3
- package/types/engine/compile-corpus.d.mts +1 -1
- package/types/engine/content-address.d.mts +11 -11
- package/types/engine/content-format-check.d.mts +6 -6
- package/types/engine/content-format.d.mts +2 -2
- package/types/engine/content-html.d.mts +78 -0
- package/types/engine/content-icons.d.mts +150 -62
- package/types/engine/content-index.d.mts +2 -2
- package/types/engine/content-links.d.mts +8 -8
- package/types/engine/content-lint.d.mts +2 -2
- package/types/engine/content-package.d.mts +6 -8
- package/types/engine/derived-fields.d.mts +101 -0
- package/types/engine/diagnostics.d.mts +2 -2
- package/types/engine/document-subtypes.d.mts +3 -3
- package/types/engine/field-spec.d.mts +37 -39
- package/types/engine/folder-notes.d.mts +4 -5
- package/types/engine/foreign-catalog.d.mts +3 -3
- package/types/engine/foundry-entries.d.mts +6 -7
- package/types/engine/frontmatter-lint.d.mts +7 -7
- package/types/engine/frontmatter.d.mts +7 -7
- package/types/engine/generate.d.mts +7 -7
- package/types/engine/helpers.d.mts +25 -27
- package/types/engine/homepage.d.mts +16 -18
- package/types/engine/ids.d.mts +13 -13
- package/types/engine/index-records.d.mts +3 -3
- package/types/engine/index.d.mts +2 -0
- package/types/engine/item-compiler.d.mts +21 -5
- package/types/engine/item-docs.d.mts +2 -2
- package/types/engine/item-registry.d.mts +6 -6
- package/types/engine/journals.d.mts +3 -3
- package/types/engine/map-notes.d.mts +2 -2
- package/types/engine/metadata-index.d.mts +4 -4
- package/types/engine/note-claims.d.mts +16 -15
- package/types/engine/note-ids.d.mts +4 -4
- package/types/engine/note-package.d.mts +1 -1
- package/types/engine/note-renames.d.mts +3 -3
- package/types/engine/note-vocabulary.d.mts +9 -8
- package/types/engine/pack-config.d.mts +3 -3
- package/types/engine/pack-router.d.mts +1 -1
- package/types/engine/prose-config.d.mts +9 -9
- package/types/engine/prose-lint.d.mts +3 -4
- package/types/engine/region-events.d.mts +2 -2
- package/types/engine/retired-fields.d.mts +10 -9
- package/types/engine/schema-check.d.mts +11 -11
- package/types/engine/site-build.d.mts +18 -19
- package/types/engine/site-index.d.mts +3 -4
- package/types/engine/sql-tables.d.mts +11 -5
- package/types/engine/subtype-registry.d.mts +3 -3
- package/types/engine/system-block.d.mts +3 -3
- package/types/engine/web-wikilinks.d.mts +7 -7
- package/types/engine/wikilink-syntax.d.mts +17 -17
- package/types/engine/wikilinks.d.mts +13 -12
- package/types/hm3/actors.d.mts +1 -1
- package/types/hm3/document-subtypes.d.mts +1 -1
- package/types/hm3/items.d.mts +1 -2
- package/types/hm3/template-priority.d.mts +1 -1
- package/types/manifest.d.mts +8 -8
- package/types/sohl/actors.d.mts +2 -2
- package/types/sohl/affiliation-standings.d.mts +2 -2
- package/types/sohl/being-info.d.mts +2 -2
- package/types/sohl/document-subtypes.d.mts +1 -1
- package/types/sohl/items.d.mts +1 -2
- package/types/sohl/note-schemas.d.mts +1 -1
- package/MIGRATING.md +0 -608
package/bin/content-build.mjs
CHANGED
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
* configuration, directory creation, reading the shipped Foundry package
|
|
21
21
|
* manifest, and the process exit code. The library itself is import-safe, so a
|
|
22
22
|
* consuming repository's build — or a test — can call it without any of this
|
|
23
|
-
* happening
|
|
23
|
+
* happening.
|
|
24
24
|
*
|
|
25
25
|
* The side effects that need *configuration* live inside the command handler,
|
|
26
26
|
* not at module scope, so `--version` and `--help` answer in a directory that
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
* either is missing.
|
|
30
30
|
*
|
|
31
31
|
* Every path and pack name it hands the library comes from the consuming
|
|
32
|
-
* repository's `package-build.config.yaml
|
|
32
|
+
* repository's `package-build.config.yaml`, located by
|
|
33
33
|
* `engine/pack-config.mjs`; nothing about any one repository's layout is
|
|
34
34
|
* written here.
|
|
35
35
|
*
|
|
@@ -80,6 +80,7 @@ import {
|
|
|
80
80
|
import { renderItemFieldReference } from "../engine/field-reference.mjs";
|
|
81
81
|
import { lintContentTree } from "../engine/content-lint.mjs";
|
|
82
82
|
import { lintContentCharset } from "../engine/content-charset.mjs";
|
|
83
|
+
import { lintContentHtml } from "../engine/content-html.mjs";
|
|
83
84
|
import { lintContentIcons } from "../engine/content-icons.mjs";
|
|
84
85
|
import { declaredSystems, lintFrontmatter, systemBlocksFor } from "../engine/frontmatter-lint.mjs";
|
|
85
86
|
import { loadContentFormat } from "../engine/content-format.mjs";
|
|
@@ -96,14 +97,14 @@ import {
|
|
|
96
97
|
} from "../engine/schema-check.mjs";
|
|
97
98
|
// The one vocabulary, loaded whole. Every content project authors the full type
|
|
98
99
|
// set — an adventure module ships skills, beings and magic swords — so no
|
|
99
|
-
// consumer gets a subset
|
|
100
|
+
// consumer gets a subset.
|
|
100
101
|
import { NOTE_SCHEMAS } from "../sohl/note-schemas.mjs";
|
|
101
102
|
// The shipped declarations, so this repository can check its own specification
|
|
102
|
-
// against them without standing up a consumer's configuration
|
|
103
|
+
// against them without standing up a consumer's configuration.
|
|
103
104
|
import { ITEM_FIELDS } from "../sohl/item-fields.mjs";
|
|
104
105
|
import { HM3_ITEM_FIELDS } from "../hm3/item-fields.mjs";
|
|
105
106
|
// The engine's own types, merged under the registry's so the vocabulary stands
|
|
106
|
-
// in a package that configures no `itemBuilders` at all
|
|
107
|
+
// in a package that configures no `itemBuilders` at all.
|
|
107
108
|
import { ENGINE_NOTE_SCHEMAS } from "../engine/note-schemas.mjs";
|
|
108
109
|
import { schemaSubtypeOf } from "../engine/subtype-registry.mjs";
|
|
109
110
|
import { NOTE_VOCABULARY } from "../engine/note-vocabulary.mjs";
|
|
@@ -122,7 +123,7 @@ import {
|
|
|
122
123
|
} from "../engine/site-build.mjs";
|
|
123
124
|
import { auditLinks, buildLinkIndex, walkReachability } from "../engine/content-links.mjs";
|
|
124
125
|
import { prepareTreeSqlTables } from "../engine/sql-tables.mjs";
|
|
125
|
-
// The one place a link finding is worded, shared with both builds
|
|
126
|
+
// The one place a link finding is worded, shared with both builds.
|
|
126
127
|
import { linkFindingMessage } from "../engine/wikilink-syntax.mjs";
|
|
127
128
|
import {
|
|
128
129
|
emitDiagnostic,
|
|
@@ -144,7 +145,7 @@ import { emittedArtFor, itemPackJsonDirs } from "../engine/generate.mjs";
|
|
|
144
145
|
* The packs `unpack` extracts.
|
|
145
146
|
*
|
|
146
147
|
* From the configuration's own pack list, which is where the build already
|
|
147
|
-
* knows them. It
|
|
148
|
+
* knows them. It does not come out of the shipped manifest — a second
|
|
148
149
|
* declaration of the same list, in a second format, with nothing checking that
|
|
149
150
|
* the two agreed. The manifest is generated from this list now
|
|
150
151
|
* (package-build#9), so reading it back would be a round trip through an
|
|
@@ -166,7 +167,7 @@ function configuredPacks() {
|
|
|
166
167
|
* defaults to the *nearest* `package.json` walking up from the working
|
|
167
168
|
* directory — inside a consuming repository that is the consumer's manifest, so
|
|
168
169
|
* `content-build --version` reported the consumer's version instead of the
|
|
169
|
-
* toolchain's
|
|
170
|
+
* toolchain's.
|
|
170
171
|
*
|
|
171
172
|
* @returns {string} The `version` field of this package's manifest.
|
|
172
173
|
*/
|
|
@@ -191,8 +192,8 @@ prefix.apply(log, {
|
|
|
191
192
|
/**
|
|
192
193
|
* Report a command's failure.
|
|
193
194
|
*
|
|
194
|
-
* A configuration error carries its own `file:line:column: error: ` locator
|
|
195
|
-
*
|
|
195
|
+
* A configuration error carries its own `file:line:column: error: ` locator,
|
|
196
|
+
* and `loglevel`'s `[timestamp] [ERROR]:` prefix occupies exactly the
|
|
196
197
|
* position a parser reads the path from — so a located failure is printed
|
|
197
198
|
* unprefixed, as `emitDiagnostic` prints every other finding. Everything else
|
|
198
199
|
* is ordinary prose and keeps the log line it always had.
|
|
@@ -249,10 +250,10 @@ const argv = yargs(hideBin(process.argv))
|
|
|
249
250
|
.version(ownVersion())
|
|
250
251
|
.help()
|
|
251
252
|
.alias("help", "h")
|
|
252
|
-
// Every invocation this CLI accepts must be one it performs
|
|
253
|
+
// Every invocation this CLI accepts must be one it performs. yargs
|
|
253
254
|
// gives neither guarantee by default: without `demandCommand` a bare
|
|
254
255
|
// `content-build` exits 0 in silence, and without `strict` an unknown
|
|
255
|
-
// command or option is ignored rather than reported. Both
|
|
256
|
+
// command or option is ignored rather than reported. Both would read as
|
|
256
257
|
// success from a `run-s` chain, so a typo in a build script passed the step
|
|
257
258
|
// it was meant to run. The sibling toolchain `@heroiclands/package-build`
|
|
258
259
|
// opts into the same two.
|
|
@@ -264,7 +265,7 @@ const argv = yargs(hideBin(process.argv))
|
|
|
264
265
|
*
|
|
265
266
|
* The page is generated from the `fields` each `itemBuilders` entry declares,
|
|
266
267
|
* so every consuming repository documents *its own* registry with the same
|
|
267
|
-
* command
|
|
268
|
+
* command.
|
|
268
269
|
*
|
|
269
270
|
* **The framing comes from configuration**, because the tables are the only
|
|
270
271
|
* part that is the same everywhere. A repository's `docs.itemFields` says what
|
|
@@ -288,10 +289,10 @@ function docsCommand() {
|
|
|
288
289
|
command: "docs <action>",
|
|
289
290
|
describe: "Generate documentation from the configured registries",
|
|
290
291
|
builder: (yargs) => {
|
|
291
|
-
// Required and honoured
|
|
292
|
+
// Required and honoured, not optional and unread:
|
|
292
293
|
// the handler rendered the item-field reference whatever it was
|
|
293
294
|
// given, so the positional constrained what could be typed and
|
|
294
|
-
// selected nothing
|
|
295
|
+
// selected nothing.
|
|
295
296
|
yargs.positional("action", {
|
|
296
297
|
describe: "The document to render.",
|
|
297
298
|
type: "string",
|
|
@@ -380,7 +381,7 @@ function docsCommand() {
|
|
|
380
381
|
}
|
|
381
382
|
|
|
382
383
|
/**
|
|
383
|
-
* `content-build content-format` — check the format specification itself
|
|
384
|
+
* `content-build content-format` — check the format specification itself.
|
|
384
385
|
*
|
|
385
386
|
* Two checks, because the specification makes claims about two different
|
|
386
387
|
* worlds, and they fail for different reasons and at different times:
|
|
@@ -389,10 +390,9 @@ function docsCommand() {
|
|
|
389
390
|
* naming system's published `schema.json`. A failure means the specification
|
|
390
391
|
* and the system disagree, which is a defect in one of the two.
|
|
391
392
|
* - `fields` compares the per-type tables against the field declarations that
|
|
392
|
-
* compile them, so the hand-written half cannot drift from the generated one
|
|
393
|
-
* (#136).
|
|
393
|
+
* compile them, so the hand-written half cannot drift from the generated one.
|
|
394
394
|
* - `notes` measures a content tree against the vocabulary the document
|
|
395
|
-
* declares per type. During
|
|
395
|
+
* declares per type. During the migration it is the progress bar rather
|
|
396
396
|
* than a gate, so it **reports** by default and `--strict` makes it fatal —
|
|
397
397
|
* turned on one class at a time as each slice lands.
|
|
398
398
|
*
|
|
@@ -535,7 +535,7 @@ function declarationsFrom(argv) {
|
|
|
535
535
|
* The specification hand-writes a `data` table under most of its type sections,
|
|
536
536
|
* covering ground {@link module:engine/field-reference} already generates from
|
|
537
537
|
* the `fields` on each `itemBuilders` entry — the duplication that module exists
|
|
538
|
-
* to prevent, one document over
|
|
538
|
+
* to prevent, one document over.
|
|
539
539
|
*
|
|
540
540
|
* **Checked, not merged.** The document's vocabulary spans note types that
|
|
541
541
|
* produce Scenes, Macros and JournalEntries, which no item registry covers, so
|
|
@@ -566,7 +566,7 @@ function contentFormatFieldsCommand() {
|
|
|
566
566
|
});
|
|
567
567
|
yargs.option("coverage", {
|
|
568
568
|
describe:
|
|
569
|
-
"List, per type, the fields only one side names. They are not findings — the two vocabularies differ by design until
|
|
569
|
+
"List, per type, the fields only one side names. They are not findings — the two vocabularies differ by design until the corpus moves.",
|
|
570
570
|
type: "boolean",
|
|
571
571
|
default: false,
|
|
572
572
|
});
|
|
@@ -627,8 +627,8 @@ function contentFormatFieldsCommand() {
|
|
|
627
627
|
*
|
|
628
628
|
* **A report, not a gate.** Every authored note predates the format, so a
|
|
629
629
|
* failing check would be red in every repository from the day it lands and
|
|
630
|
-
* would stay red for the length of
|
|
631
|
-
* `--strict` raises the findings to errors,
|
|
630
|
+
* would stay red for the length of the migration — which is a check nobody
|
|
631
|
+
* can act on. `--strict` raises the findings to errors, turned on slice by
|
|
632
632
|
* slice as each class of finding reaches zero.
|
|
633
633
|
*
|
|
634
634
|
* @returns {object} The yargs command module.
|
|
@@ -649,7 +649,7 @@ function contentFormatNotesCommand() {
|
|
|
649
649
|
});
|
|
650
650
|
yargs.option("strict", {
|
|
651
651
|
describe:
|
|
652
|
-
"Fail on the findings instead of reporting them. Turned on per slice
|
|
652
|
+
"Fail on the findings instead of reporting them. Turned on per slice, as each class reaches zero.",
|
|
653
653
|
type: "boolean",
|
|
654
654
|
default: false,
|
|
655
655
|
});
|
|
@@ -660,7 +660,7 @@ function contentFormatNotesCommand() {
|
|
|
660
660
|
const root = argv.root ?? config.paths.content;
|
|
661
661
|
const format = specFrom(argv);
|
|
662
662
|
|
|
663
|
-
// The corpus from the index, like every other check
|
|
663
|
+
// The corpus from the index, like every other check.
|
|
664
664
|
// A report measuring the tree against the declared vocabulary
|
|
665
665
|
// has to be looking at the same tree the compile will, or its
|
|
666
666
|
// counts describe a corpus nobody builds.
|
|
@@ -745,14 +745,14 @@ function lintCommand() {
|
|
|
745
745
|
const root = argv.root ?? config.paths.content;
|
|
746
746
|
|
|
747
747
|
// The corpus, enumerated once for this command and handed to
|
|
748
|
-
// every pass below, rather than derived again by each
|
|
748
|
+
// every pass below, rather than derived again by each.
|
|
749
749
|
// The address lint reads it, the `sql` tables select over it
|
|
750
750
|
// and the link index is built from it, so no two findings this
|
|
751
751
|
// command reports can be drawn from different ideas of which
|
|
752
752
|
// files the content is.
|
|
753
753
|
//
|
|
754
754
|
// A note the index cannot record is reported like any other
|
|
755
|
-
// finding rather than thrown
|
|
755
|
+
// finding rather than thrown: one malformed note must
|
|
756
756
|
// not take every other finding in the tree with it, and the
|
|
757
757
|
// reader needs a line to open, not a stack.
|
|
758
758
|
const corpusProblems = [];
|
|
@@ -768,7 +768,7 @@ function lintCommand() {
|
|
|
768
768
|
// would call the tree clean while silently omitting a note.
|
|
769
769
|
if (corpusProblems.length) process.exitCode = 1;
|
|
770
770
|
|
|
771
|
-
// The package is passed for the homepage rule
|
|
771
|
+
// The package is passed for the homepage rule, which
|
|
772
772
|
// names the address a tree with no front page fails to serve.
|
|
773
773
|
const addresses = lintContentTree(root, {
|
|
774
774
|
contentPackage: config.contentPackage,
|
|
@@ -790,7 +790,7 @@ function lintCommand() {
|
|
|
790
790
|
}),
|
|
791
791
|
});
|
|
792
792
|
// Which system blocks this tree carries, derived from what it
|
|
793
|
-
// declares it ships for
|
|
793
|
+
// declares it ships for. Read before the lint so the
|
|
794
794
|
// systems it will *not* check can be said out loud below.
|
|
795
795
|
// `schemaSystem` names whose vocabulary the `schemas` below
|
|
796
796
|
// are. They are `sohl/note-schemas.mjs`, imported here
|
|
@@ -823,18 +823,18 @@ function lintCommand() {
|
|
|
823
823
|
}
|
|
824
824
|
const frontmatter = lintFrontmatter(index, {
|
|
825
825
|
schemas: { ...ENGINE_NOTE_SCHEMAS, ...NOTE_SCHEMAS },
|
|
826
|
-
// The closed frontmatter regions
|
|
826
|
+
// The closed frontmatter regions. Passed in rather
|
|
827
827
|
// than reached for, so the linter stays a checker of
|
|
828
828
|
// whatever it is handed and this stays the one place that
|
|
829
829
|
// decides which vocabulary a tree is held to.
|
|
830
830
|
vocabulary: NOTE_VOCABULARY,
|
|
831
831
|
// The pack names, for a `data:` field keyed by pack — a
|
|
832
|
-
// folder's `parent` is one
|
|
832
|
+
// folder's `parent` is one. Companions included:
|
|
833
833
|
// the compile asks the map for whichever pack it is
|
|
834
834
|
// writing, and a companion is a pack it writes.
|
|
835
835
|
packs: config.packDirectories,
|
|
836
836
|
// What art each type actually reaches its document through,
|
|
837
|
-
// asked of the passes rather than listed here
|
|
837
|
+
// asked of the passes rather than listed here. This
|
|
838
838
|
// is the one place that decides what a tree is held to, so
|
|
839
839
|
// it is where the derivation is handed over — the linter
|
|
840
840
|
// states no list of iconless types of its own.
|
|
@@ -850,7 +850,7 @@ function lintCommand() {
|
|
|
850
850
|
});
|
|
851
851
|
|
|
852
852
|
// What the builders emit, against what the receiving system
|
|
853
|
-
// declares
|
|
853
|
+
// declares. Reported here rather than at compile: it is
|
|
854
854
|
// a property of the *declarations*, not of any one note, so it
|
|
855
855
|
// is the same answer for every document and belongs where a
|
|
856
856
|
// reader is already being told about the vocabulary.
|
|
@@ -900,7 +900,7 @@ function lintCommand() {
|
|
|
900
900
|
artifact: schema.artifact,
|
|
901
901
|
// A schema is keyed by document subtype and a field
|
|
902
902
|
// declaration by note type. Those were one string until
|
|
903
|
-
//
|
|
903
|
+
// Three are renamed, and joining them by name
|
|
904
904
|
// after that would drop `armorgear`'s findings without
|
|
905
905
|
// saying so — the seam exists for exactly this.
|
|
906
906
|
subtypeOf: (type) => schemaSubtypeOf(config.stats?.systemId, type),
|
|
@@ -924,25 +924,33 @@ function lintCommand() {
|
|
|
924
924
|
}
|
|
925
925
|
}
|
|
926
926
|
|
|
927
|
-
// The charset the tree is held to, so a book can pick its face
|
|
928
|
-
//
|
|
927
|
+
// The charset the tree is held to, so a book can pick its face.
|
|
928
|
+
// Run over the raw files rather than the parsed notes:
|
|
929
929
|
// the subject is every character authored, including the ones
|
|
930
930
|
// that stopped a note parsing at all.
|
|
931
931
|
const charset = lintContentCharset(root, {
|
|
932
932
|
skipDirectories: config.skipDirectories,
|
|
933
933
|
});
|
|
934
934
|
|
|
935
|
-
// The names the charset check leaves room for
|
|
935
|
+
// The names the charset check leaves room for. An icon
|
|
936
936
|
// the registry does not declare renders as its own literal
|
|
937
937
|
// text, which is visible but easy to publish, so it is reported
|
|
938
938
|
// here rather than left for a reader to notice.
|
|
939
939
|
//
|
|
940
|
-
// The
|
|
941
|
-
//
|
|
942
|
-
//
|
|
943
|
-
// being read here before anything declares it.
|
|
940
|
+
// The configured registry — the shipped table with this
|
|
941
|
+
// package's own entries merged over it, which is where a
|
|
942
|
+
// Game-Icons glyph becomes a name a note may write.
|
|
944
943
|
const icons = lintContentIcons(root, {
|
|
945
944
|
skipDirectories: config.skipDirectories,
|
|
945
|
+
registry: config.icons,
|
|
946
|
+
});
|
|
947
|
+
|
|
948
|
+
// The markup the charset check cannot see. Class names are
|
|
949
|
+
// ASCII, so a page of `<i class="fa-…">` is allowlist-clean and
|
|
950
|
+
// still unrenderable in a book — the character rule one level
|
|
951
|
+
// up.
|
|
952
|
+
const html = lintContentHtml(root, {
|
|
953
|
+
skipDirectories: config.skipDirectories,
|
|
946
954
|
});
|
|
947
955
|
|
|
948
956
|
const findings = [
|
|
@@ -951,9 +959,10 @@ function lintCommand() {
|
|
|
951
959
|
...schemaFindings,
|
|
952
960
|
...charset.findings,
|
|
953
961
|
...icons.findings,
|
|
962
|
+
...html.findings,
|
|
954
963
|
];
|
|
955
964
|
// Only an **error** fails the run. Every finding was an error
|
|
956
|
-
//
|
|
965
|
+
// by then, so this changes nothing on its own —
|
|
957
966
|
// but a field retired in favour of another is reported while
|
|
958
967
|
// both spellings still compile, and failing a build over a note
|
|
959
968
|
// that produces the correct document would red a tree that has
|
|
@@ -1002,7 +1011,7 @@ function lintCommand() {
|
|
|
1002
1011
|
* reports, as warnings, each shared convention the repository's own
|
|
1003
1012
|
* configuration resolves differently — or that it declares no configuration at
|
|
1004
1013
|
* all, which guarantees an editor and a bare `npx prettier` disagree with this
|
|
1005
|
-
* command about the same tree
|
|
1014
|
+
* command about the same tree. Nothing there fails the run: the point is
|
|
1006
1015
|
* that a local choice is deliberate rather than silent.
|
|
1007
1016
|
*
|
|
1008
1017
|
* @returns {object} The yargs command module.
|
|
@@ -1040,7 +1049,7 @@ function formatCommand() {
|
|
|
1040
1049
|
const root = process.cwd();
|
|
1041
1050
|
// Before the per-file report, because it is the context for it:
|
|
1042
1051
|
// which rules this run applied, and whether anything else in
|
|
1043
|
-
// the repository applies the same ones
|
|
1052
|
+
// the repository applies the same ones. Warnings only —
|
|
1044
1053
|
// a consumer's config wins by design, so none of this touches
|
|
1045
1054
|
// the exit code.
|
|
1046
1055
|
const conventions = await checkPrettierConventions(root);
|
|
@@ -1065,7 +1074,7 @@ function formatCommand() {
|
|
|
1065
1074
|
// `--write` collects findings too — a file Prettier cannot
|
|
1066
1075
|
// parse, or one that will not format to a fixpoint — and
|
|
1067
1076
|
// used to discard them, so a run that had left files
|
|
1068
|
-
// unformatted still reported success and exited 0
|
|
1077
|
+
// unformatted still reported success and exited 0.
|
|
1069
1078
|
for (const finding of findings) emitDiagnostic(finding);
|
|
1070
1079
|
if (findings.length) {
|
|
1071
1080
|
log.error(
|
|
@@ -1166,7 +1175,7 @@ function linksCommand() {
|
|
|
1166
1175
|
const contentBase = argv.root ?? config.paths.content;
|
|
1167
1176
|
|
|
1168
1177
|
const scope = { skipDirectories: config.skipDirectories };
|
|
1169
|
-
// Enumerated once and shared, as in `lint
|
|
1178
|
+
// Enumerated once and shared, as in `lint`, and a note
|
|
1170
1179
|
// it cannot record is reported rather than thrown.
|
|
1171
1180
|
const corpusProblems = [];
|
|
1172
1181
|
const records = indexRecordsFor({
|
|
@@ -1238,8 +1247,8 @@ function linksCommand() {
|
|
|
1238
1247
|
`heading in ${d.dest.rel} declares`,
|
|
1239
1248
|
});
|
|
1240
1249
|
}
|
|
1241
|
-
// Every link is an address
|
|
1242
|
-
// resolve
|
|
1250
|
+
// Every link is an address and every address must
|
|
1251
|
+
// resolve, so all of these are errors — but they read
|
|
1243
1252
|
// differently because the corrections differ. The wording comes
|
|
1244
1253
|
// from the shared table, so the checker cannot describe a
|
|
1245
1254
|
// defect differently from the build that also refuses it.
|
|
@@ -1265,7 +1274,7 @@ function linksCommand() {
|
|
|
1265
1274
|
// The package homepage. Its addresses are markdown links and
|
|
1266
1275
|
// `landing:` url/href fields rather than wikilinks — it is
|
|
1267
1276
|
// published verbatim, so nothing resolves a wikilink on it —
|
|
1268
|
-
// and
|
|
1277
|
+
// and nothing else looks at them.
|
|
1269
1278
|
for (const h of homepageLinks) {
|
|
1270
1279
|
emitDiagnostic({
|
|
1271
1280
|
file: h.note.file,
|
|
@@ -1307,7 +1316,7 @@ function linksCommand() {
|
|
|
1307
1316
|
*
|
|
1308
1317
|
* Every build already walks the tree and parses every note's frontmatter, then
|
|
1309
1318
|
* throws the result away, so nothing outside a build can ask a question about
|
|
1310
|
-
* the content
|
|
1319
|
+
* the content. This publishes that walk as JSON Lines: one record per
|
|
1311
1320
|
* note, carrying the whole frontmatter plus the note's place in the tree.
|
|
1312
1321
|
*
|
|
1313
1322
|
* It is a command of its own rather than only a build step because the point of
|
|
@@ -1358,7 +1367,7 @@ function contentIndexCommand() {
|
|
|
1358
1367
|
* `content-build site` — publish the content tree as a website.
|
|
1359
1368
|
*
|
|
1360
1369
|
* The sibling of `package compile`: the same tree, rendered as pages instead of
|
|
1361
|
-
* compiled into packs
|
|
1370
|
+
* compiled into packs. Everything a consumer would otherwise write for itself —
|
|
1362
1371
|
* the walk, the address derivation, the address index, table expansion,
|
|
1363
1372
|
* wikilink resolution, code-fence protection, the foreign-manifest merge and
|
|
1364
1373
|
* the section-landing backfill — happens here, from configuration.
|
|
@@ -1394,7 +1403,7 @@ function siteCommand() {
|
|
|
1394
1403
|
// First, because it is decided before the tree is walked and
|
|
1395
1404
|
// before the output is cleared: a package with no front page,
|
|
1396
1405
|
// or two competing for it, has nothing to say about its pages
|
|
1397
|
-
// yet
|
|
1406
|
+
// yet.
|
|
1398
1407
|
for (const f of gates.homepages) emitDiagnostic(f);
|
|
1399
1408
|
for (const f of gates.frontmatterLinks) {
|
|
1400
1409
|
emitDiagnostic({
|
|
@@ -1440,7 +1449,7 @@ function siteCommand() {
|
|
|
1440
1449
|
// was prose with a timestamp where a parser reads the path,
|
|
1441
1450
|
// which made one authored table produce a machine-readable
|
|
1442
1451
|
// diagnostic from one build and something ungreppable from the
|
|
1443
|
-
// other
|
|
1452
|
+
// other.
|
|
1444
1453
|
for (const e of result.tableErrors) {
|
|
1445
1454
|
emitDiagnostic({
|
|
1446
1455
|
file: e.source,
|
|
@@ -1452,7 +1461,7 @@ function siteCommand() {
|
|
|
1452
1461
|
}
|
|
1453
1462
|
// Reported the way the pack build reports the very same
|
|
1454
1463
|
// finding: `file:line:column: error: message`, path first, and
|
|
1455
|
-
// the message from the shared table
|
|
1464
|
+
// the message from the shared table, not a
|
|
1456
1465
|
// `log.error` whose timestamp prefix sat where a parser reads
|
|
1457
1466
|
// the path from, and whose text named a `reason` code rather
|
|
1458
1467
|
// than saying what to do — so one authored link produced a
|
|
@@ -1531,7 +1540,7 @@ function reachabilityCommand() {
|
|
|
1531
1540
|
try {
|
|
1532
1541
|
// Resolved once and passed on, so every pass below runs
|
|
1533
1542
|
// against the configuration this command resolved rather than
|
|
1534
|
-
// whichever one the working directory answers with
|
|
1543
|
+
// whichever one the working directory answers with.
|
|
1535
1544
|
const config = loadPackConfig();
|
|
1536
1545
|
const contentBase = argv.root ?? config.paths.content;
|
|
1537
1546
|
const dir = String(argv.dir).replace(/\/+$/, "");
|
|
@@ -1604,7 +1613,7 @@ function reachabilityCommand() {
|
|
|
1604
1613
|
// eslint-disable-next-line
|
|
1605
1614
|
/**
|
|
1606
1615
|
* `deps fetch` — fill the caches this build resolves other packages through:
|
|
1607
|
-
* the **content index** of every declared dependency
|
|
1616
|
+
* the **content index** of every declared dependency, and the **item
|
|
1608
1617
|
* catalogue** of those additionally declaring `itemCatalog: true`.
|
|
1609
1618
|
*
|
|
1610
1619
|
* The two sets differ deliberately. Citing another package's *addresses* and
|
|
@@ -1664,7 +1673,7 @@ function depsCommand() {
|
|
|
1664
1673
|
command: "deps <action>",
|
|
1665
1674
|
describe: "Manage build-time dependencies on other packages",
|
|
1666
1675
|
builder: (yargs) => {
|
|
1667
|
-
// Required, for the reason `package <action>` is
|
|
1676
|
+
// Required, for the reason `package <action>` is: an optional
|
|
1668
1677
|
// action exits 0 having done nothing.
|
|
1669
1678
|
yargs.positional("action", {
|
|
1670
1679
|
describe: "The action to perform.",
|
|
@@ -1761,7 +1770,7 @@ async function diffAddresses(config, argv) {
|
|
|
1761
1770
|
);
|
|
1762
1771
|
}
|
|
1763
1772
|
|
|
1764
|
-
// Stated by the caller, like every other corpus read in this file
|
|
1773
|
+
// Stated by the caller, like every other corpus read in this file:
|
|
1765
1774
|
// the two tree reads below must agree with each other and with the compile
|
|
1766
1775
|
// about which files are the corpus. They now do so by construction — the
|
|
1767
1776
|
// corpus is derived once, here, and handed to both.
|
|
@@ -1823,7 +1832,7 @@ function addressesCommand() {
|
|
|
1823
1832
|
command: "addresses <action>",
|
|
1824
1833
|
describe: "Compare the addresses this build publishes against a release's",
|
|
1825
1834
|
builder: (yargs) => {
|
|
1826
|
-
// Required, for the reason every other action is
|
|
1835
|
+
// Required, for the reason every other action is: an
|
|
1827
1836
|
// optional one exits 0 having compared nothing.
|
|
1828
1837
|
yargs.positional("action", {
|
|
1829
1838
|
describe: "The action to perform.",
|
|
@@ -1875,7 +1884,7 @@ function packageCommand() {
|
|
|
1875
1884
|
builder: (yargs) => {
|
|
1876
1885
|
// Required, not optional: the action *is* the work, and an
|
|
1877
1886
|
// optional one meant `content-build package` fell through the
|
|
1878
|
-
// switch below and exited 0 having compiled nothing
|
|
1887
|
+
// switch below and exited 0 having compiled nothing.
|
|
1879
1888
|
yargs.positional("action", {
|
|
1880
1889
|
describe: "The action to perform.",
|
|
1881
1890
|
type: "string",
|
|
@@ -1907,7 +1916,7 @@ function packageCommand() {
|
|
|
1907
1916
|
switch (action) {
|
|
1908
1917
|
// Every path and pack list the library needs is defaulted
|
|
1909
1918
|
// from the resolved configuration, so nothing is restated
|
|
1910
|
-
// here
|
|
1919
|
+
// here.
|
|
1911
1920
|
case "compile":
|
|
1912
1921
|
return await compilePacks({ packName: pack });
|
|
1913
1922
|
case "clean":
|
package/bin/package-build.mjs
CHANGED
|
@@ -133,7 +133,7 @@ function die(err) {
|
|
|
133
133
|
const message = err instanceof Error ? err.message : String(err);
|
|
134
134
|
// A located diagnostic already starts with `file:line:column:`, which is
|
|
135
135
|
// exactly the position a parser reads the path from — prefixing it would
|
|
136
|
-
// yield a filename no editor can open
|
|
136
|
+
// yield a filename no editor can open.
|
|
137
137
|
console.error(
|
|
138
138
|
/** @type {{located?: boolean}} */ (err)?.located ? message : `package-build: ${message}`,
|
|
139
139
|
);
|
|
@@ -325,7 +325,7 @@ async function formatGenerated(text, filepath) {
|
|
|
325
325
|
*
|
|
326
326
|
* The producing half of the check `content-build lint` runs: Foundry discards
|
|
327
327
|
* an unknown `system` key at construction and says nothing, so a content build
|
|
328
|
-
* needs to know what a document will actually receive
|
|
328
|
+
* needs to know what a document will actually receive. It cannot ask a
|
|
329
329
|
* running Foundry, and it cannot read `defineSchema()` from a sibling checkout,
|
|
330
330
|
* so the system publishes the field sets as data — the same shape the link
|
|
331
331
|
* manifest already uses for addresses.
|
package/config.mjs
CHANGED
|
@@ -29,10 +29,8 @@
|
|
|
29
29
|
* loader checks that the section is a mapping and hands it back frozen;
|
|
30
30
|
* everything inside it is validated here.
|
|
31
31
|
*
|
|
32
|
-
* **That section
|
|
33
|
-
*
|
|
34
|
-
* carried on behalf of a toolchain it knew nothing about. One package now owns
|
|
35
|
-
* the whole file, so it is an ordinary section — but the validation split is
|
|
32
|
+
* **That section is not a reservation.** One package owns the whole file, so
|
|
33
|
+
* `packageBuild:` is an ordinary section — but the validation split is
|
|
36
34
|
* kept, because it is what stops a key being checked twice against two
|
|
37
35
|
* disagreeing ideas of what it means.
|
|
38
36
|
*
|
|
@@ -150,7 +148,7 @@ const ARTIFACT_OF_KIND = Object.freeze({
|
|
|
150
148
|
*
|
|
151
149
|
* The dotted path rides on the error as `field` as well as appearing in the
|
|
152
150
|
* message, so {@link loadPackageBuildConfig} — the half that knows which file
|
|
153
|
-
* was read — can resolve it to a line and column
|
|
151
|
+
* was read — can resolve it to a line and column. This half stays pure.
|
|
154
152
|
*
|
|
155
153
|
* @param {string} where - Dotted path of the offending key.
|
|
156
154
|
* @param {string} problem - What is wrong with it.
|
|
@@ -802,8 +800,8 @@ export function resolvePackageBuildConfig(shared) {
|
|
|
802
800
|
e2eSuite: normalizeE2ESuite(e2eInput.suite),
|
|
803
801
|
// Declaring nothing keeps the old contract — the suite's exit status is
|
|
804
802
|
// taken at its word. Declaring where results land is what lets the
|
|
805
|
-
// harness tell "the suite ran and passed" from "the suite did not run"
|
|
806
|
-
//
|
|
803
|
+
// harness tell "the suite ran and passed" from "the suite did not run";
|
|
804
|
+
// a repository that wants that distinction has to say where to
|
|
807
805
|
// look for it, because the harness does not know what the suite is.
|
|
808
806
|
e2eResults: normalizeGlobs(e2eInput.results, [], "packageBuild.e2e.results"),
|
|
809
807
|
e2eBuild,
|
|
@@ -831,7 +829,7 @@ export function loadPackageBuildConfig() {
|
|
|
831
829
|
} catch (err) {
|
|
832
830
|
// The pure half names the offending key and nothing else; this half
|
|
833
831
|
// knows the file it was read from, so the position is attached here
|
|
834
|
-
//
|
|
832
|
+
// — the same boundary `configFromData` is for the rest of the
|
|
835
833
|
// configuration.
|
|
836
834
|
throw locateConfigError(err, packConfigPath());
|
|
837
835
|
}
|