@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
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* tree in reverse. Order was load-bearing here when the address index carried
|
|
6
6
|
* first-writer-wins fallbacks for a page's name, filename and slug — reversing
|
|
7
7
|
* the walk silently changed which page an ambiguous name resolved to. Those
|
|
8
|
-
* fallbacks are gone with the bare `[[Name]]` form
|
|
8
|
+
* fallbacks are gone with the bare `[[Name]]` form, so this is now
|
|
9
9
|
* ordinary reading order rather than a dependency; it is kept because a site's
|
|
10
10
|
* emitted pages should not reorder for no reason.
|
|
11
11
|
*
|
|
@@ -51,13 +51,13 @@ export function collectTreePages(tree: object, ctx: object): {
|
|
|
51
51
|
* it, because in homepage-only mode it is the **whole** of the site build: the
|
|
52
52
|
* content tree is never read for pages at all, so the licensing constraint two
|
|
53
53
|
* packages ship under is a property of the code path rather than of a
|
|
54
|
-
* configuration that happens to be empty
|
|
54
|
+
* configuration that happens to be empty.
|
|
55
55
|
*
|
|
56
56
|
* Returned as a list rather than as the one note there should be, because the
|
|
57
|
-
* count is what {@link checkHomepageCount} judges
|
|
57
|
+
* count is what {@link checkHomepageCount} judges — this walk reports
|
|
58
58
|
* what it found, and {@link buildSite} decides whether that is one.
|
|
59
59
|
*
|
|
60
|
-
* A homepage that declares no `shortcode` has no address
|
|
60
|
+
* A homepage that declares no `shortcode` has no address, and is
|
|
61
61
|
* reported rather than written: it is the same finding a content page's missing
|
|
62
62
|
* shortcode produces, and it has to be available in homepage-only mode, where
|
|
63
63
|
* no other gate runs.
|
|
@@ -85,13 +85,13 @@ export function collectHomepages(contentBase: string, ctx: object): {
|
|
|
85
85
|
* for, and would make homepage-only mode depend on the index, the foreign
|
|
86
86
|
* manifests and the table universe that mode exists to not build.
|
|
87
87
|
*
|
|
88
|
-
* **Verbatim is the answer
|
|
88
|
+
* **Verbatim is the answer, not a gap.** A landing's links
|
|
89
89
|
* could not be *resolved* here without giving `homepage` mode the index its
|
|
90
90
|
* licensing fence exists to not build, so they are **checked** instead:
|
|
91
91
|
* {@link auditHomepageLinks} reads the `landing:` addresses and the body's
|
|
92
92
|
* markdown links, and reports a wikilink on the page rather than resolving one.
|
|
93
93
|
*
|
|
94
|
-
* **Its destination is no longer fixed
|
|
94
|
+
* **Its destination is no longer fixed**. The file is written at the
|
|
95
95
|
* note's address, flat at the package's site root, and the page states that
|
|
96
96
|
* address as its `url` — the same separation of file from URL every other page
|
|
97
97
|
* has. Nothing is written at `/<package>/` itself: that becomes a redirect the
|
|
@@ -117,8 +117,7 @@ export function writeHomepages(outRoot: string, pages: readonly object[], config
|
|
|
117
117
|
* - **Addresses** next: a note that has no address — no shortcode to be
|
|
118
118
|
* addressed by, or no section to be filed under — would silently drop a page.
|
|
119
119
|
* There is no collision gate beside it: an address is `(type, shortcode)`,
|
|
120
|
-
* which is unique within a package by rule, so two pages cannot claim one URL
|
|
121
|
-
* (#181).
|
|
120
|
+
* which is unique within a package by rule, so two pages cannot claim one URL.
|
|
122
121
|
* - **Foreign manifests** last, in two steps. *Unusable* is a file this build
|
|
123
122
|
* cannot read; *unaddressable* is one it can read but cannot look anything up
|
|
124
123
|
* in — a distinction worth keeping, because the second surfaces as a pile of
|
|
@@ -167,7 +166,7 @@ export function tableUniverse(pages: object[]): Map<string, object[]>;
|
|
|
167
166
|
* a value YAML can carry, and would abort the serializer.
|
|
168
167
|
*
|
|
169
168
|
* Everything else the section declared is passed through. That is the point of
|
|
170
|
-
* the function:
|
|
169
|
+
* the function: two writers transcribing `title` and `banner` by
|
|
171
170
|
* name, so the vocabulary lived in three places — the schema that admits a key
|
|
172
171
|
* and the two writers that copy it — and a key added to the schema alone
|
|
173
172
|
* validated cleanly and then reached no page. The *schema* is the bound worth
|
|
@@ -182,7 +181,7 @@ export function sectionFrontmatter(meta: object): object;
|
|
|
182
181
|
/**
|
|
183
182
|
* The frontmatter a page publishes with.
|
|
184
183
|
*
|
|
185
|
-
* An authored `aliases` is retired
|
|
184
|
+
* An authored `aliases` is retired and refused before a build reaches
|
|
186
185
|
* here, which makes this a guard rather than a working path. It was Obsidian's
|
|
187
186
|
* — a list of *names* a reader might call
|
|
188
187
|
* the note, which is vault addressing and stays in the vault. Hugo reads
|
|
@@ -191,13 +190,13 @@ export function sectionFrontmatter(meta: object): object;
|
|
|
191
190
|
* redirects of its own.
|
|
192
191
|
*
|
|
193
192
|
* A content page states its own **`url`**, which is its address rather than its
|
|
194
|
-
* path
|
|
193
|
+
* path. It is written flat under the content mount, so Hugo would
|
|
195
194
|
* otherwise publish it at `<mount><type>-<shortcode>/` rather than at the
|
|
196
195
|
* package-wide address the link manifest records — the same address, one
|
|
197
196
|
* segment too deep. So the address is stated and the mount does not reach it.
|
|
198
197
|
*
|
|
199
|
-
* **It is stated relative to the site root, and so carries no package base
|
|
200
|
-
*
|
|
198
|
+
* **It is stated relative to the site root, and so carries no package base**.
|
|
199
|
+
* Hugo resolves a `url` against `baseURL`, whose path is already where
|
|
201
200
|
* the package is served — a consumer's Hugo site *is* its package — so writing
|
|
202
201
|
* `page.url`, which carries the base for every href this build renders, wrote
|
|
203
202
|
* that base a second time and published every content page a segment too deep
|
|
@@ -206,8 +205,8 @@ export function sectionFrontmatter(meta: object): object;
|
|
|
206
205
|
* index a wikilink resolves through, and the link manifest — composes
|
|
207
206
|
* `<base><slug>/`.
|
|
208
207
|
*
|
|
209
|
-
* A content page carries the package the build **derived
|
|
210
|
-
* declares one — `package:` is retired
|
|
208
|
+
* A content page carries the package the build **derived**. No note
|
|
209
|
+
* declares one — `package:` is retired — so the note's frontmatter alone
|
|
211
210
|
* would publish a page that does not say which package it belongs to. The
|
|
212
211
|
* emitted page is what a
|
|
213
212
|
* theme reads: `breadcrumbs.html` builds its middle crumb from
|
|
@@ -228,9 +227,9 @@ export function pageFrontmatter(page: object, { readmeSections, decorate }: obje
|
|
|
228
227
|
/**
|
|
229
228
|
* Where a page is written, relative to the output root.
|
|
230
229
|
*
|
|
231
|
-
* **Flat, under the mount, named by its address
|
|
230
|
+
* **Flat, under the mount, named by its address**. A content page's URL
|
|
232
231
|
* is its address — `/<package>/<type>-<shortcode>/` — and the file is now named
|
|
233
|
-
* the same way, so the two agree.
|
|
232
|
+
* the same way, so the two agree. Filing it into `<section>/` so that
|
|
234
233
|
* Hugo would read a section off its path; a section appears in no address, and
|
|
235
234
|
* a directory chosen only to satisfy a rendering engine's idea of what a
|
|
236
235
|
* section is has no business in the note format.
|
|
@@ -238,7 +237,7 @@ export function pageFrontmatter(page: object, { readmeSections, decorate }: obje
|
|
|
238
237
|
* The name is the *whole* address rather than a section-relative half of it, so
|
|
239
238
|
* two types cannot fight over one file: a `doc` note's `subType` may be spelled
|
|
240
239
|
* the same as another note's `type`, and `doc-gear.md` and `weapongear-gear.md`
|
|
241
|
-
* are distinct whatever the sections
|
|
240
|
+
* are distinct whatever the sections.
|
|
242
241
|
*
|
|
243
242
|
* **A `trees` entry is the exception, and always was.** Those pages preserve
|
|
244
243
|
* their source layout below a named section — they are a book with chapters,
|
|
@@ -274,7 +273,7 @@ export function renderPages(pages: object[], options: object): {
|
|
|
274
273
|
/**
|
|
275
274
|
* Writes the Hugo sections a published tree declares.
|
|
276
275
|
*
|
|
277
|
-
* **This is where a section lives now, and the only place
|
|
276
|
+
* **This is where a section lives now, and the only place**. A content
|
|
278
277
|
* note carries none: it is addressed by `(type, shortcode)` and emitted flat
|
|
279
278
|
* under the mount, so nothing a page does creates a directory. A site that wants
|
|
280
279
|
* `/<package>/<prefix><section>/` to answer — with a title, a hero, and whatever
|
|
@@ -38,7 +38,7 @@ export function buildSiteIndex(entries: readonly SiteEntry[], { foreignIndex }?:
|
|
|
38
38
|
*
|
|
39
39
|
* There is deliberately **no `manifestsComplete`**. It used to let a resolver
|
|
40
40
|
* soften an unresolved cross-package address while any package's manifest was
|
|
41
|
-
* missing;
|
|
41
|
+
* missing; the softening is retired, since the pack compilers and the link
|
|
42
42
|
* checker never had it and one authored link must not get two verdicts. A
|
|
43
43
|
* caller still passing it is ignored rather than obeyed.
|
|
44
44
|
*/
|
|
@@ -76,8 +76,7 @@ export type SiteEntry = {
|
|
|
76
76
|
* The Hugo section a **tree** page is filed under, and
|
|
77
77
|
* the first segment of the `<sec>/<slug>` address it
|
|
78
78
|
* is reachable by. A content page has none: it is
|
|
79
|
-
* addressed by `(type, shortcode)` and emitted flat
|
|
80
|
-
* (#204).
|
|
79
|
+
* addressed by `(type, shortcode)` and emitted flat.
|
|
81
80
|
*/
|
|
82
81
|
sec?: string | undefined;
|
|
83
82
|
/**
|
|
@@ -101,7 +100,7 @@ export type SiteIndex = {
|
|
|
101
100
|
/**
|
|
102
101
|
* Address → page. `draft` says the page
|
|
103
102
|
* carries the `draft` tag, which marks a
|
|
104
|
-
* link *into* it
|
|
103
|
+
* link *into* it.
|
|
105
104
|
*/
|
|
106
105
|
index: Map<string, {
|
|
107
106
|
url: string;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Every `sql` fence in a markdown body, with the position each occupies.
|
|
3
3
|
*
|
|
4
4
|
* Positions are 0-based lines into the body as given, which is what a diagnostic
|
|
5
|
-
* about a directive needs
|
|
5
|
+
* about a directive needs and what the expander uses to splice results
|
|
6
6
|
* back in.
|
|
7
7
|
*
|
|
8
8
|
* @param {string} markdown - The note body, frontmatter already stripped.
|
|
@@ -47,7 +47,7 @@ export function findSqlBlocks(markdown: string): Array<{
|
|
|
47
47
|
* It is `FROM` rather than a fence property naming a file, for two reasons. A
|
|
48
48
|
* path in authored content is a build artifact's name written into the corpus,
|
|
49
49
|
* so renaming the artifact means sweeping every note that cites it — the
|
|
50
|
-
* coupling
|
|
50
|
+
* coupling the corpus move exists to undo. And *which dataset a query reads* is what
|
|
51
51
|
* `FROM` is for: the same rule that keeps `_ref` and `_section` ordinary SQL,
|
|
52
52
|
* visible where an author is already looking, rather than fence options.
|
|
53
53
|
*
|
|
@@ -95,6 +95,11 @@ export function runSqlQuery(db: object, sql: string): Promise<{
|
|
|
95
95
|
* authored `ORDER BY` decides the section order too, and one query replaces the
|
|
96
96
|
* forty near-identical blocks the language used to require.
|
|
97
97
|
*
|
|
98
|
+
* **A result selecting nothing still renders its header and rule.** The finding
|
|
99
|
+
* is the point, not withholding the output: an authored heading with an empty
|
|
100
|
+
* table under it says the query ran and matched nothing, where a heading with
|
|
101
|
+
* *nothing* under it reads as a page that failed to build.
|
|
102
|
+
*
|
|
98
103
|
* @param {{columns: string[], rows: object[]}} result - From
|
|
99
104
|
* {@link runSqlQuery}.
|
|
100
105
|
* @param {object} [opts]
|
|
@@ -117,7 +122,7 @@ export function renderSqlTable(result: {
|
|
|
117
122
|
* {@link module:engine/content-tables.expandContentTables} is not — nor should
|
|
118
123
|
* it become so: two of its three callers are synchronous, and one of those,
|
|
119
124
|
* `renderPages`, is exported. Preparing the results first keeps every one of
|
|
120
|
-
* those signatures intact, and it is the shape
|
|
125
|
+
* those signatures intact, and it is the shape the index is heading for anyway —
|
|
121
126
|
* the corpus enumerated once, each pass reading the answer rather than
|
|
122
127
|
* deriving it again.
|
|
123
128
|
*
|
|
@@ -149,7 +154,8 @@ export function prepareSqlTables(db: object, sources: Array<{
|
|
|
149
154
|
* Answer every `sql` directive in a content tree.
|
|
150
155
|
*
|
|
151
156
|
* The one entry point each pass uses, so the compiler, the link checker and the
|
|
152
|
-
* site build cannot disagree about what a table selects — the failure mode
|
|
157
|
+
* site build cannot disagree about what a table selects — the failure mode the
|
|
158
|
+
* shared index
|
|
153
159
|
* describes, where N passes each derive the corpus their own way.
|
|
154
160
|
*
|
|
155
161
|
* **Nothing is opened for a tree with no `sql` directive.** The corpus is still
|
|
@@ -163,7 +169,7 @@ export function prepareSqlTables(db: object, sources: Array<{
|
|
|
163
169
|
* @param {readonly string[]} [opts.skipDirectories] - The walk's scope.
|
|
164
170
|
* @param {object[]} [opts.records] - Index records the caller already derived.
|
|
165
171
|
* A command that also builds a link index holds them already, and deriving
|
|
166
|
-
* them twice is the duplicated-corpus failure
|
|
172
|
+
* them twice is the duplicated-corpus failure this closes.
|
|
167
173
|
* @returns {Promise<Map<string, object[]>|undefined>} Results by note path, or
|
|
168
174
|
* nothing when the tree has no such directive.
|
|
169
175
|
*/
|
|
@@ -11,7 +11,7 @@ export function subtypeMapFor(system: string | undefined): import("./document-su
|
|
|
11
11
|
* translation the *schema* check needs, and the reason it needs one.
|
|
12
12
|
*
|
|
13
13
|
* A schema artifact is keyed by document subtype; a field declaration is keyed
|
|
14
|
-
* by note type. Those
|
|
14
|
+
* by note type. Those would be the same string but for three renames, and
|
|
15
15
|
* a check that went on joining them by name simply stopped reporting on
|
|
16
16
|
* `armorgear` — a warning that vanishes is worse than one that fires, because
|
|
17
17
|
* nothing says it went.
|
|
@@ -29,7 +29,7 @@ export function schemaSubtypeOf(system: string | undefined, type: string): strin
|
|
|
29
29
|
/**
|
|
30
30
|
* The note-type → document-subtype maps this toolchain ships.
|
|
31
31
|
*
|
|
32
|
-
* Two, since `hm3/` landed
|
|
32
|
+
* Two, since `hm3/` landed — and it joined this list rather than the
|
|
33
33
|
* claim table growing a second copy of the same fact, which is what the list
|
|
34
34
|
* was for.
|
|
35
35
|
*
|
|
@@ -55,7 +55,7 @@ export const KNOWN_DOCUMENT_SUBTYPE_MAPS: readonly import("./document-subtypes.m
|
|
|
55
55
|
* {@link KNOWN_DOCUMENT_SUBTYPE_MAPS} exists rather than a hand-kept table.
|
|
56
56
|
*
|
|
57
57
|
* It exists because an actor note publishes documentation like every other
|
|
58
|
-
* system-bearing note
|
|
58
|
+
* system-bearing note. `docEntryTypes` was `itemTypes` plus `macro` and
|
|
59
59
|
* the map types, which left a being as the one system-bearing note with no
|
|
60
60
|
* `none` address — nothing a prose link could land on, since its only address
|
|
61
61
|
* named the Actor. Composing that set needs to know which types are actors, and
|
|
@@ -117,7 +117,7 @@ export function legacyKeyOf(field: {
|
|
|
117
117
|
/**
|
|
118
118
|
* The bare top-level key a `data:`-sourced field is being swept off — step 3b.
|
|
119
119
|
*
|
|
120
|
-
* `data:`
|
|
120
|
+
* `data:` did not invent the facts it holds; it *gathered* them, out of
|
|
121
121
|
* the note's open top level where each was a sibling of `img` and `shortcode`.
|
|
122
122
|
* So the retiring spelling of `data.portrait` is not a second declaration
|
|
123
123
|
* anyone has to write — it is `portrait`, mechanically, and the same holds for
|
|
@@ -208,7 +208,7 @@ export function systemDataPaths(data: Record<string, unknown>, prefix?: string):
|
|
|
208
208
|
*
|
|
209
209
|
* It stayed invisible while those maps were authored *outside* `<system>.system`
|
|
210
210
|
* and so were never walked. The moment the corpus moves them to the destination
|
|
211
|
-
*
|
|
211
|
+
* every one of them lights up — 62 findings on `sohl-thalorna` alone,
|
|
212
212
|
* none of them a defect.
|
|
213
213
|
*
|
|
214
214
|
* So descent is conditional on the schema declaring something *beneath* the
|
|
@@ -237,7 +237,7 @@ export function undeclaredPaths(data: Record<string, unknown>, declared: Readonl
|
|
|
237
237
|
* @param {object} options - Options.
|
|
238
238
|
* @param {Iterable<string>} options.known - The keys this system declares on
|
|
239
239
|
* top of the shared vocabulary: its generators, its toolchain keys, and —
|
|
240
|
-
* until
|
|
240
|
+
* until the corpus moves them — the field names its notes still author in the
|
|
241
241
|
* block.
|
|
242
242
|
* @returns {string[]} The unrecognized keys, in authored order.
|
|
243
243
|
*/
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Every wikilink authored inside a frontmatter value
|
|
2
|
+
* Every wikilink authored inside a frontmatter value.
|
|
3
3
|
*
|
|
4
4
|
* Wikilinks are resolved in a note's **body** — by {@link resolveWebWikilinks}
|
|
5
5
|
* here, and by the pack compilers' `convertWikilinks` for Foundry. Frontmatter
|
|
@@ -36,19 +36,19 @@ export function frontmatterWikilinks(fm: unknown): Array<{
|
|
|
36
36
|
* `section/slug`), then in the vendored `ctx.foreign` manifests. A target is a
|
|
37
37
|
* *partial* address: an omitted package means this package, an omitted system
|
|
38
38
|
* is a wildcard, and exactly one match resolves — two are `ambiguous`. A link written
|
|
39
|
-
* without a label addresses nothing at all and is reported as such
|
|
39
|
+
* without a label addresses nothing at all and is reported as such —
|
|
40
40
|
* there is no second namespace left for it to name.
|
|
41
41
|
*
|
|
42
42
|
* Only a slash-qualified target reaches the raw key, which is what keeps
|
|
43
43
|
* `section/slug` addressable without a page's own slug answering for it.
|
|
44
44
|
*
|
|
45
|
-
* **Every target that resolves nowhere fails the build
|
|
45
|
+
* **Every target that resolves nowhere fails the build**, and is
|
|
46
46
|
* classified into the vocabulary all three resolvers share — `unlabelled`,
|
|
47
47
|
* `not-an-address`, `unknown-type`, `ambiguous`, `unresolved`. Failures are
|
|
48
48
|
* collected in `ctx.errors`, each carrying the authored `link` and its
|
|
49
49
|
* `occurrence` so a caller can report the line and column it sits on.
|
|
50
50
|
*
|
|
51
|
-
* There
|
|
51
|
+
* There is deliberately no exception letting a hyphen-form address through while
|
|
52
52
|
* any linkable package had no vendored manifest, since a real cross-package
|
|
53
53
|
* reference and a typo look identical from here. The pack compilers and the
|
|
54
54
|
* link checker never made that allowance, so its only surviving effect was to
|
|
@@ -56,13 +56,13 @@ export function frontmatterWikilinks(fm: unknown): Array<{
|
|
|
56
56
|
* instead.
|
|
57
57
|
*
|
|
58
58
|
* A target that resolves nowhere still renders through {@link unresolvedLink}
|
|
59
|
-
* rather than as bare prose
|
|
59
|
+
* rather than as bare prose: the author's text is kept, marked so a
|
|
60
60
|
* reader can see a link was intended. The marking and the failure are separate
|
|
61
61
|
* jobs and always were — the mark is for whoever reads the page a *previous*
|
|
62
62
|
* build emitted, the failure is for the author of this one.
|
|
63
63
|
*
|
|
64
64
|
* A target that **resolved** to an entry with no page is not this case and is
|
|
65
|
-
* not marked: a pack-only package
|
|
65
|
+
* not marked: a pack-only package publishes Foundry addresses and no
|
|
66
66
|
* web pages, so the author wrote a real address and there is simply nothing to
|
|
67
67
|
* link to.
|
|
68
68
|
*
|
|
@@ -71,7 +71,7 @@ export function frontmatterWikilinks(fm: unknown): Array<{
|
|
|
71
71
|
* foreign, type, errors, src, file }`.
|
|
72
72
|
* `packages` is every package an address may name, without which the leading
|
|
73
73
|
* package segment of a canonical address reads as an unknown type; `foreign`
|
|
74
|
-
* is the cross-package manifest index
|
|
74
|
+
* is the cross-package manifest index. `src` is the page's display
|
|
75
75
|
* path and `file` the source file a diagnostic should name — absent, `src`
|
|
76
76
|
* stands in.
|
|
77
77
|
* @returns {string} The body with wikilinks rewritten.
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* @property {string|null} display - The text after `|`, or `null` when the link
|
|
11
11
|
* is unlabelled. `null` and `""` differ: an author may write `[[x|]]`.
|
|
12
12
|
* @property {boolean} labelled - Whether a `|` was present at all. A link
|
|
13
|
-
* without one addresses nothing and is a finding
|
|
13
|
+
* without one addresses nothing and is a finding — see
|
|
14
14
|
* {@link unlabelledLinkMessage} — so every reader has to be able to ask.
|
|
15
15
|
*/
|
|
16
16
|
/**
|
|
@@ -32,12 +32,12 @@ export function parseWikilink(rawInner: string): ParsedWikilink;
|
|
|
32
32
|
* `display: null` does. The two are still distinguishable through
|
|
33
33
|
* {@link ParsedWikilink.labelled}, which is the thing that genuinely differs:
|
|
34
34
|
* `[[x|]]` is labelled and `[[x]]` is not, and only the first addresses
|
|
35
|
-
* anything
|
|
35
|
+
* anything.
|
|
36
36
|
*
|
|
37
37
|
* Stated here because the two resolvers had already drawn the line in two
|
|
38
38
|
* places and drawn it differently: the packs tested falsiness and were right,
|
|
39
39
|
* the web tested `??` — which falls through on `null` only — and emitted
|
|
40
|
-
* `[](/url/)`, a link with no clickable text, through every build
|
|
40
|
+
* `[](/url/)`, a link with no clickable text, through every build. That
|
|
41
41
|
* is the same drift this module exists to prevent, in the case its own
|
|
42
42
|
* {@link ParsedWikilink} docstring calls out. One reading, one place.
|
|
43
43
|
*
|
|
@@ -56,12 +56,12 @@ export function authoredLabel({ display }: {
|
|
|
56
56
|
* the form to write rather than a value to correct: there is no value that
|
|
57
57
|
* makes an unlabelled link resolve.
|
|
58
58
|
*
|
|
59
|
-
* **Why there is nothing left for a bare link to mean
|
|
59
|
+
* **Why there is nothing left for a bare link to mean**. The pipe used
|
|
60
60
|
* to select between two namespaces — address and alias — and the alias one was
|
|
61
61
|
* empty in practice: across 8,305 wikilinks in three content trees, not one
|
|
62
62
|
* bare `[[Alias]]` resolved to a note. What the index it looked up in *did* do
|
|
63
63
|
* was fold every note's `name.full` into itself, which forbade two notes of a
|
|
64
|
-
* type from sharing a display name
|
|
64
|
+
* type from sharing a display name. So the namespace is gone, every
|
|
65
65
|
* link is an address, and an address needs the pipe that says so.
|
|
66
66
|
*
|
|
67
67
|
* The **link part may still be an anchor**: `[[#slug|Text]]` addresses a
|
|
@@ -80,12 +80,12 @@ export function unlabelledLinkMessage(target: string): string;
|
|
|
80
80
|
* package publishing it is not a declared dependency — or is one whose index
|
|
81
81
|
* has not been fetched — and the link itself looks identical in every case.
|
|
82
82
|
*
|
|
83
|
-
*
|
|
83
|
+
* As a **warning** in the checker and, in the site build, nothing
|
|
84
84
|
* at all until every linkable package's manifest was accounted for — on the
|
|
85
85
|
* reasoning that a bare `[[Name]]` might be a placeholder for a note nobody had
|
|
86
|
-
* written yet. That reasoning was a property of the bare form, which is retired
|
|
87
|
-
*
|
|
88
|
-
* that exists and resolves and renders marked
|
|
86
|
+
* written yet. That reasoning was a property of the bare form, which is retired;
|
|
87
|
+
* the intent behind it now has a real spelling, a `draft`-tagged note
|
|
88
|
+
* that exists and resolves and renders marked. So an address naming no
|
|
89
89
|
* note is a typo or an omission, both want fixing, and all three builds say so.
|
|
90
90
|
*
|
|
91
91
|
* @param {string} target - The address as authored, named in the message.
|
|
@@ -101,9 +101,9 @@ export function unresolvedAddressMessage(target: string): string;
|
|
|
101
101
|
* message names the claimants so the author can choose between them without
|
|
102
102
|
* going looking.
|
|
103
103
|
*
|
|
104
|
-
* **The correction is the canonical form**, all four segments
|
|
104
|
+
* **The correction is the canonical form**, all four segments. Omission
|
|
105
105
|
* runs strictly left to right, so there is no `package-type-shortcode` to offer
|
|
106
|
-
* — naming a package means naming the system before the type. That
|
|
106
|
+
* — naming a package means naming the system before the type. That would be
|
|
107
107
|
* the correction here, back when a written target could state three segments at
|
|
108
108
|
* most; the grammar is positional now, and a three-segment target names a
|
|
109
109
|
* *system*, not a package.
|
|
@@ -166,7 +166,7 @@ export function isSamePage({ target, anchor }: ParsedWikilink): boolean;
|
|
|
166
166
|
* The web side's pattern omitted `\n` from the excluded set, so an unclosed
|
|
167
167
|
* bracket consumed everything up to the next `]]` anywhere in the document —
|
|
168
168
|
* the same shape of corruption a hand-rolled code-fence regex caused on the one
|
|
169
|
-
* page whose subject is link syntax
|
|
169
|
+
* page whose subject is link syntax. It was also internally
|
|
170
170
|
* inconsistent: its *frontmatter* scan excluded newlines while its body scan did
|
|
171
171
|
* not.
|
|
172
172
|
*
|
|
@@ -182,7 +182,7 @@ export function isSamePage({ target, anchor }: ParsedWikilink): boolean;
|
|
|
182
182
|
* ({@link LINK_FINDING_REASONS}) and the message each one reports through
|
|
183
183
|
* ({@link linkFindingMessage}). Three builds read one authored link; an author
|
|
184
184
|
* meets whichever ran first, and a consumer switching on a `reason` should not
|
|
185
|
-
* be switching on which build produced it
|
|
185
|
+
* be switching on which build produced it.
|
|
186
186
|
*
|
|
187
187
|
* @module
|
|
188
188
|
*/
|
|
@@ -196,16 +196,16 @@ export function isSamePage({ target, anchor }: ParsedWikilink): boolean;
|
|
|
196
196
|
*/
|
|
197
197
|
export const WIKILINK: RegExp;
|
|
198
198
|
/**
|
|
199
|
-
* Every way a link can fail, named once for all three resolvers
|
|
199
|
+
* Every way a link can fail, named once for all three resolvers.
|
|
200
200
|
*
|
|
201
201
|
* A link is read in three places — the checker (`content-links.mjs`), the pack
|
|
202
202
|
* compilers (`wikilinks.mjs`) and the web resolver (`web-wikilinks.mjs`) — and
|
|
203
|
-
* each
|
|
203
|
+
* each would otherwise name the failures in its own words. `unknown` in one is
|
|
204
204
|
* `unresolved` in another and `broken type/shortcode` in the third, so a
|
|
205
205
|
* consumer switching on a `reason` was switching on which build had produced
|
|
206
206
|
* it. The set is closed and lives here, beside the syntax the three share.
|
|
207
207
|
*
|
|
208
|
-
* - `unlabelled` — no `|`, so the link addresses nothing
|
|
208
|
+
* - `unlabelled` — no `|`, so the link addresses nothing.
|
|
209
209
|
* - `not-an-address` — labelled, but the target does not parse as an address.
|
|
210
210
|
* - `unknown-type` — definitely qualified, but names no type this build knows.
|
|
211
211
|
* - `unresolved` — parses as an address, and nothing publishes it.
|
|
@@ -240,7 +240,7 @@ export type ParsedWikilink = {
|
|
|
240
240
|
display: string | null;
|
|
241
241
|
/**
|
|
242
242
|
* - Whether a `|` was present at all. A link
|
|
243
|
-
* without one addresses nothing and is a finding
|
|
243
|
+
* without one addresses nothing and is a finding — see
|
|
244
244
|
* {@link unlabelledLinkMessage} — so every reader has to be able to ask.
|
|
245
245
|
*/
|
|
246
246
|
labelled: boolean;
|
|
@@ -3,15 +3,15 @@
|
|
|
3
3
|
* not one.
|
|
4
4
|
*
|
|
5
5
|
* A document and its documentation are two documents in two packs, so they
|
|
6
|
-
* need two addresses
|
|
6
|
+
* need two addresses. `skill/wpnc` is the item; `docskill/wpnc` is the
|
|
7
7
|
* JournalEntry its prose compiled into, and `docmacro/autoattack` is the same
|
|
8
|
-
* arrangement for a macro
|
|
8
|
+
* arrangement for a macro.
|
|
9
9
|
*
|
|
10
10
|
* The virtual form exists for a type that carries separate documentation
|
|
11
11
|
* ({@link sohl.utils.packs.docEntryTypes} — the set the journals compiler and
|
|
12
12
|
* the link manifest read too), **or** for one that routes to the items pack.
|
|
13
13
|
* The second clause is the older rule and stays: types that compile into items
|
|
14
|
-
* are the open, unenumerated set
|
|
14
|
+
* are the open, unenumerated set, and a foreign package may publish an
|
|
15
15
|
* item type this build has never heard of. Dropping it would silently unlink
|
|
16
16
|
* every `doc<type>` address into such a package.
|
|
17
17
|
*
|
|
@@ -31,8 +31,8 @@ export function resolveItemDocType(qualifier: string, types: Set<string>): strin
|
|
|
31
31
|
* Two separators are accepted, and they are **not** interchangeable in how
|
|
32
32
|
* confidently they mark a target as qualified:
|
|
33
33
|
*
|
|
34
|
-
* - **`type-shortcode`** and its qualified forms — the canonical spelling
|
|
35
|
-
*
|
|
34
|
+
* - **`type-shortcode`** and its qualified forms — the canonical spelling.
|
|
35
|
+
* Obsidian reads `/` inside a wikilink as a *path* and resolves it
|
|
36
36
|
* against the vault's folders, so a slash-qualified link is a broken link in
|
|
37
37
|
* the editor where the content is now authored.
|
|
38
38
|
* - **`type/shortcode`** — the legacy form, still resolved so that a link
|
|
@@ -41,7 +41,7 @@ export function resolveItemDocType(qualifier: string, types: Set<string>): strin
|
|
|
41
41
|
* before it is reported rather than guessed at. The split is at the **last**
|
|
42
42
|
* slash, as it always was.
|
|
43
43
|
*
|
|
44
|
-
* **The grammar is strict, and omission runs left to right
|
|
44
|
+
* **The grammar is strict, and omission runs left to right**:
|
|
45
45
|
*
|
|
46
46
|
* ```text
|
|
47
47
|
* [[[[<package>-]<system>-]<type>-]<shortcode>]
|
|
@@ -56,12 +56,13 @@ export function resolveItemDocType(qualifier: string, types: Set<string>): strin
|
|
|
56
56
|
* **Parsing is plain positional counting**, the same rule
|
|
57
57
|
* {@link readCanonicalKey} follows, and it is sound for the same reason: every
|
|
58
58
|
* segment is `^[A-Za-z0-9]+$` (`ADDRESS_SEGMENT_PATTERN`, enforced on
|
|
59
|
-
* shortcodes by `content-lint.mjs`
|
|
59
|
+
* shortcodes by `content-lint.mjs`), so the hyphen is purely a
|
|
60
60
|
* separator and the count alone determines every field. Verified across the
|
|
61
61
|
* four content trees: 138,204 authored shortcodes, none carrying a separator.
|
|
62
62
|
*
|
|
63
63
|
* That replaced a first-hyphen split which let a shortcode contain a hyphen
|
|
64
|
-
* (`trauma-self-pro` → `trauma` + `self-pro`). The tolerance predates
|
|
64
|
+
* (`trauma-self-pro` → `trauma` + `self-pro`). The tolerance predates the
|
|
65
|
+
* charset rule and
|
|
65
66
|
* outlived it; no tree has used it, and keeping it would make a three-segment
|
|
66
67
|
* target ambiguous between a system and a hyphenated shortcode.
|
|
67
68
|
*
|
|
@@ -120,7 +121,7 @@ export function anchorPageId(noteId: string, anchorSlug: string): string;
|
|
|
120
121
|
* One entry per content note. `pack` / `docPack` name the packs the note's
|
|
121
122
|
* document and its documentation entry landed in; omitted, the conventional
|
|
122
123
|
* one-pack-per-type names stand in. `draft` says the note carries the `draft`
|
|
123
|
-
* tag, which marks links *into* it and changes nothing else
|
|
124
|
+
* tag, which marks links *into* it and changes nothing else.
|
|
124
125
|
* @param {string} packageId - The Foundry package shipping the packs; the first
|
|
125
126
|
* segment of every emitted UUID.
|
|
126
127
|
* @param {Map<string, object>} [foreign] - Canonically keyed entries from
|
|
@@ -153,7 +154,7 @@ export function buildWikilinkIndex(docs: Array<{
|
|
|
153
154
|
*
|
|
154
155
|
* **Code is verbatim.** A `[[…]]` inside a fenced or indented code block, or
|
|
155
156
|
* inside an inline code span, is source text an author wrote to be read as
|
|
156
|
-
* written, so it is left alone and not reported
|
|
157
|
+
* written, so it is left alone and not reported. Without that, a
|
|
157
158
|
* script sample containing `grid[[0]]` became a link — and only for some
|
|
158
159
|
* array shapes, `[[1,2],[3,4]]` having an inner `]` the pattern cannot cross,
|
|
159
160
|
* so the corruption looked arbitrary. It reaches the reader through the
|
|
@@ -174,10 +175,10 @@ export function buildWikilinkIndex(docs: Array<{
|
|
|
174
175
|
* @returns {{markdown: string, unresolved: Array<{link: string, target: string,
|
|
175
176
|
* offset: number, reason: string, packages?: string[], anchor?: string}>}}
|
|
176
177
|
* Each `reason` is one of {@link LINK_FINDING_REASONS}, the vocabulary all
|
|
177
|
-
* three resolvers share
|
|
178
|
+
* three resolvers share — `ambiguous` carries the claiming `packages`
|
|
178
179
|
* and `unknown-anchor` the section it named. `offset` is the link's 0-based
|
|
179
180
|
* position in `markdown`, which is what lets a caller report the line and
|
|
180
|
-
* column it sits on
|
|
181
|
+
* column it sits on.
|
|
181
182
|
*/
|
|
182
183
|
export function convertWikilinks(markdown: string, { type, id, pack, docPack, index }: {
|
|
183
184
|
type: string;
|
package/types/hm3/actors.d.mts
CHANGED
|
@@ -35,7 +35,7 @@ export class Hm3Actors extends SystemActorCompiler {
|
|
|
35
35
|
* template priority.
|
|
36
36
|
*
|
|
37
37
|
* The rule itself is {@link module:hm3/template-priority.templateFlags},
|
|
38
|
-
* because the Item pass writes the same flag from the same statement
|
|
38
|
+
* because the Item pass writes the same flag from the same statement
|
|
39
39
|
* and two copies of it were one copy too many — this pass had the only one,
|
|
40
40
|
* and the Item pass had none.
|
|
41
41
|
*
|
|
@@ -17,7 +17,7 @@ export const HM3_TYPE_KEY: string;
|
|
|
17
17
|
* map does not name — `affiliation`, `affliction`, `attribute`,
|
|
18
18
|
* `concoction`, `mystery`, and every core type — compile into no HM3
|
|
19
19
|
* document at all, silently and correctly: HM3 has no form of them, and a
|
|
20
|
-
* finding on every such note would be the noise
|
|
20
|
+
* finding on every such note would be the noise the rule exists to prevent.
|
|
21
21
|
*
|
|
22
22
|
* @type {import("../engine/document-subtypes.mjs").DocumentSubtypeMap}
|
|
23
23
|
*/
|
package/types/hm3/items.d.mts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
export class Hm3Items extends SystemItemCompiler {
|
|
2
2
|
/**
|
|
3
3
|
* HM3's note-type → document-subtype map — the one declaration that says
|
|
4
|
-
* which block this pass reads, which notes it claims, and what each becomes
|
|
5
|
-
* (#58/#79).
|
|
4
|
+
* which block this pass reads, which notes it claims, and what each becomes.
|
|
6
5
|
*
|
|
7
6
|
* @type {import("../engine/document-subtypes.mjs").DocumentSubtypeMap}
|
|
8
7
|
*/
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* A note that is not a template — or states nothing — writes nothing, rather
|
|
6
6
|
* than a `null` nothing reads.
|
|
7
7
|
*
|
|
8
|
-
* **Read through the shared resolver, not a field declaration
|
|
8
|
+
* **Read through the shared resolver, not a field declaration**. A
|
|
9
9
|
* `FieldSpec`'s shared source is a single position, and this value has five:
|
|
10
10
|
* `data:`, this block, the top level, and the retiring `archetype` spelling in
|
|
11
11
|
* the latter two. The resolver is the single implementation of what a note said,
|
package/types/manifest.d.mts
CHANGED
|
@@ -43,7 +43,7 @@ export function releaseUrls({ repoUrl, version, artifact }: {
|
|
|
43
43
|
download: string;
|
|
44
44
|
};
|
|
45
45
|
/**
|
|
46
|
-
* Where this release publishes its content index
|
|
46
|
+
* Where this release publishes its content index.
|
|
47
47
|
*
|
|
48
48
|
* **Pinned to this version, like `download` and unlike `manifest`.** A
|
|
49
49
|
* consumer reaches this URL by reading the dependency's manifest, so the
|
|
@@ -66,7 +66,7 @@ export function metadataUrl({ repoUrl, version, contentPackage }: {
|
|
|
66
66
|
/**
|
|
67
67
|
* The manifest's `packs`, derived from the one pack list the build already has.
|
|
68
68
|
*
|
|
69
|
-
* The two
|
|
69
|
+
* The two are not written separately, with `package-build.config.yaml` declaring
|
|
70
70
|
* a pack's name and type, and the manifest template declared them again beside
|
|
71
71
|
* a label, a path and a system id, with nothing checking that the pairs agreed.
|
|
72
72
|
* They are one list now.
|
|
@@ -89,12 +89,12 @@ export function manifestPacks(config: object): object[];
|
|
|
89
89
|
* `styles`, `languages`), and a staged file is a different relation, checked
|
|
90
90
|
* against the stage rather than against configuration. So this is the one place
|
|
91
91
|
* a declaration can go stale against a value the build already computed — and
|
|
92
|
-
* until now nothing compared them
|
|
92
|
+
* until now nothing compared them.
|
|
93
93
|
*
|
|
94
94
|
* `HarnMaster-3-FoundryVTT` shipped the consequence: its folder named four
|
|
95
95
|
* packs, three of which had not existed since the compendium was consolidated,
|
|
96
96
|
* and omitted `items` — 1,577 of 1,597 documents, loose in Foundry's compendium
|
|
97
|
-
* browser, with the build reporting nothing
|
|
97
|
+
* browser, with the build reporting nothing.
|
|
98
98
|
*
|
|
99
99
|
* **The two findings are not the same finding**, and giving them one severity
|
|
100
100
|
* gets one of them wrong:
|
|
@@ -187,7 +187,7 @@ export function buildManifest({ config, packageJson, artifact, flags }: {
|
|
|
187
187
|
* The declared `packFolders` is checked against the derived `packs[]` first,
|
|
188
188
|
* and an unresolvable name **stops the write**: a manifest already known to
|
|
189
189
|
* describe packs the package does not ship should not reach the stage, where
|
|
190
|
-
* the next command would deploy it
|
|
190
|
+
* the next command would deploy it. See {@link packFolderFindings} for
|
|
191
191
|
* the rule and why its two findings carry different severities.
|
|
192
192
|
*
|
|
193
193
|
* @param {object} options - As {@link buildManifest}, plus where to write.
|
|
@@ -229,14 +229,14 @@ export const ARTIFACTS: readonly string[];
|
|
|
229
229
|
*
|
|
230
230
|
* `relationships` is the one manifest block with a second reader.
|
|
231
231
|
* `@heroiclands/content-build` consumes it too, and v1.8.0 added
|
|
232
|
-
* `itemCatalog: true` as an opt-in on a declared dependency
|
|
233
|
-
*
|
|
232
|
+
* `itemCatalog: true` as an opt-in on a declared dependency: it selects that
|
|
233
|
+
* package's Item packs as a resolution
|
|
234
234
|
* source for the actors pass. That is an instruction to the build, not a fact
|
|
235
235
|
* about the shipped package — Foundry's relationship schema does not define
|
|
236
236
|
* it, and someone reading a published manifest cannot tell a build directive
|
|
237
237
|
* from a declaration about what the package needs.
|
|
238
238
|
*
|
|
239
|
-
* So the block is filtered rather than copied whole
|
|
239
|
+
* So the block is filtered rather than copied whole. The rule is the
|
|
240
240
|
* distinction, not the name: a key listed here answers *how is this built?*,
|
|
241
241
|
* and every key that survives answers *what does this package depend on?*.
|
|
242
242
|
* `itemCatalog` is the first build-time key to land on a relationship and is
|
package/types/sohl/actors.d.mts
CHANGED
|
@@ -2,7 +2,7 @@ export class Actors extends SystemActorCompiler {
|
|
|
2
2
|
/**
|
|
3
3
|
* SoHL's note-type → document-subtype map — the one declaration that says
|
|
4
4
|
* which block this pass reads, which notes it claims, and what each
|
|
5
|
-
* becomes
|
|
5
|
+
* becomes. It is also what every embedded reference is translated
|
|
6
6
|
* through, which is why a subclass replaces one thing and not two.
|
|
7
7
|
*
|
|
8
8
|
* @type {import("../engine/document-subtypes.mjs").DocumentSubtypeMap}
|
|
@@ -14,7 +14,7 @@ export class Actors extends SystemActorCompiler {
|
|
|
14
14
|
*/
|
|
15
15
|
buildEmbeddedItems(itemsMap: any, actorId: any, fm: any, ctx: any): any[];
|
|
16
16
|
/**
|
|
17
|
-
* Bake each unopened skill's opening mastery level into the document
|
|
17
|
+
* Bake each unopened skill's opening mastery level into the document.
|
|
18
18
|
*
|
|
19
19
|
* A skill whose `masteryLevelBase` is still null once the note's frontmatter
|
|
20
20
|
* has been merged onto the catalogue entry is *not yet opened*, and the
|