@heroiclands/package-build 20.3.1 → 20.5.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 +351 -0
- package/CONTENT.md +322 -110
- package/README.md +21 -10
- package/bin/content-build.mjs +204 -92
- package/bin/package-build.mjs +48 -15
- package/config.mjs +6 -8
- package/content-config.mjs +518 -151
- package/docs/api.md +1352 -0
- package/docs/commands.md +1609 -0
- package/docs/configuration.md +1432 -0
- package/docs/content-format.md +73 -74
- package/docs/diagnostics.md +356 -0
- package/docs/getting-started.md +813 -0
- package/docs/project-setup.md +469 -0
- package/e2e.mjs +4 -4
- package/engine/actor-compiler.mjs +64 -61
- package/engine/address-charset.mjs +6 -6
- package/engine/address-diff.mjs +57 -52
- package/engine/anchored-sections.mjs +1 -1
- package/engine/anchors.mjs +1 -1
- package/engine/base-compiler.mjs +42 -38
- package/engine/bundle-notes.mjs +4 -4
- package/engine/bundles.mjs +17 -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 +24 -24
- 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 +196 -165
- package/engine/content-index.mjs +61 -40
- package/engine/content-links.mjs +74 -41
- package/engine/content-lint.mjs +64 -34
- package/engine/content-package.mjs +7 -9
- package/engine/content-slug.mjs +2 -2
- package/engine/content-tables.mjs +38 -34
- 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 +18 -16
- package/engine/foreign-catalog.mjs +8 -9
- package/engine/foundry-entries.mjs +19 -20
- package/engine/frontmatter-lint.mjs +95 -103
- package/engine/frontmatter.mjs +11 -11
- package/engine/generate.mjs +44 -39
- package/engine/helpers.mjs +147 -84
- package/engine/homepage.mjs +20 -22
- package/engine/ids.mjs +15 -15
- package/engine/index-records.mjs +4 -4
- package/engine/index.mjs +26 -10
- 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 +24 -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 +51 -41
- 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 -8
- package/engine/note-vocabulary.mjs +56 -54
- package/engine/pack-config.mjs +39 -25
- package/engine/pack-router.mjs +0 -0
- package/engine/pdf-build.mjs +464 -0
- package/engine/pdf-fonts.mjs +420 -0
- package/engine/pdf-render.mjs +798 -0
- package/engine/pdf-toc.mjs +525 -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 +33 -25
- package/engine/schema-check.mjs +21 -21
- package/engine/schema-extract.mjs +1 -1
- package/engine/site-build.mjs +66 -50
- 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 +41 -38
- package/engine/wikilink-syntax.mjs +16 -16
- package/engine/wikilinks.mjs +40 -42
- package/hm3/actors.mjs +30 -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 +28 -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 +66 -6
- package/sohl/actors.mjs +36 -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 +28 -6
- package/sohl/kb-passes.mjs +5 -5
- package/sohl/note-schemas.mjs +12 -12
- package/sohl/skill-base.mjs +1 -1
- package/types/content-config.d.mts +91 -39
- package/types/e2e.d.mts +3 -3
- package/types/engine/actor-compiler.d.mts +45 -40
- package/types/engine/address-charset.d.mts +6 -6
- package/types/engine/address-diff.d.mts +60 -6
- package/types/engine/base-compiler.d.mts +27 -21
- package/types/engine/bundle-notes.d.mts +3 -3
- package/types/engine/bundles.d.mts +10 -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 +20 -20
- 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 +139 -92
- package/types/engine/content-index.d.mts +59 -15
- package/types/engine/content-links.d.mts +8 -8
- package/types/engine/content-lint.d.mts +8 -6
- package/types/engine/content-package.d.mts +6 -8
- package/types/engine/content-tables.d.mts +49 -18
- 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 +10 -9
- package/types/engine/frontmatter.d.mts +7 -7
- package/types/engine/generate.d.mts +7 -7
- package/types/engine/helpers.d.mts +128 -56
- 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 +6 -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 +12 -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 +30 -22
- 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 +31 -203
- package/types/engine/pack-config.d.mts +7 -7
- package/types/engine/pack-router.d.mts +1 -1
- package/types/engine/pdf-build.d.mts +42 -0
- package/types/engine/pdf-fonts.d.mts +30 -0
- package/types/engine/pdf-render.d.mts +144 -0
- package/types/engine/pdf-toc.d.mts +114 -0
- 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/scenes.d.mts +10 -1
- package/types/engine/schema-check.d.mts +13 -13
- package/types/engine/site-build.d.mts +52 -25
- 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 +14 -14
- package/types/hm3/actors.d.mts +9 -1
- package/types/hm3/document-subtypes.d.mts +1 -1
- package/types/hm3/items.d.mts +9 -2
- package/types/hm3/template-priority.d.mts +1 -1
- package/types/manifest.d.mts +8 -8
- package/types/release.d.mts +15 -4
- package/types/sohl/actors.d.mts +12 -4
- 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 +9 -2
- package/types/sohl/note-schemas.d.mts +1 -1
- package/MIGRATING.md +0 -608
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* `body` is the trimmed raw markdown after the frontmatter block, and
|
|
6
6
|
* `description` is `body` rendered to HTML. `bodyLine` / `bodyColumn` are the
|
|
7
7
|
* 1-based **file** position of the body's first character, which is what turns
|
|
8
|
-
* an offset within `body` into a position a diagnostic can name
|
|
8
|
+
* an offset within `body` into a position a diagnostic can name — see
|
|
9
9
|
* {@link positionInBody}. If the file has no frontmatter block, returns
|
|
10
10
|
* `{ frontmatter: null, body: "", description: "" }` with a warn log, and no
|
|
11
11
|
* position: there is no body to have one.
|
|
@@ -23,28 +23,10 @@ export function parseMarkdownFile(filePath: any): {
|
|
|
23
23
|
bodyLine: number;
|
|
24
24
|
bodyColumn: number;
|
|
25
25
|
};
|
|
26
|
-
/**
|
|
27
|
-
* Recursively yields every `.md` file under `rootDir`, parsed.
|
|
28
|
-
* Yields `{ frontmatter, body, description, file, absPath, bodyLine,
|
|
29
|
-
* bodyColumn }` for each match — the last two from
|
|
30
|
-
* {@link parseMarkdownFile}, so a caller can report a position inside the
|
|
31
|
-
* body as a position in the file (#17).
|
|
32
|
-
* Silently skips directories that don't exist.
|
|
33
|
-
*
|
|
34
|
-
* Directory names in `skipDirectories` are ignored wherever they appear. The
|
|
35
|
-
* walk itself knows nothing about what they mean: `Templates/` is an Obsidian
|
|
36
|
-
* templater convention this repository's vault happens to use, not a property
|
|
37
|
-
* of a content tree, so it is configured rather than hard-coded (#1508).
|
|
38
|
-
*
|
|
39
|
-
* @param {string} rootDir - Root of the tree to walk.
|
|
40
|
-
* @param {object} [opts]
|
|
41
|
-
* @param {readonly string[]} [opts.skipDirectories] - Directory names to ignore.
|
|
42
|
-
* Defaults to the configured list.
|
|
43
|
-
*/
|
|
44
26
|
/**
|
|
45
27
|
* Refuse a corpus read whose scope its caller did not state.
|
|
46
28
|
*
|
|
47
|
-
* The rule
|
|
29
|
+
* The rule in one place, so every reader of the tree refuses the same
|
|
48
30
|
* way and says so in the same words. It is shared rather than repeated because
|
|
49
31
|
* the corpus is no longer read only by {@link walkMarkdownTree}: a pass that
|
|
50
32
|
* reads the content index instead is making the identical claim about which
|
|
@@ -68,7 +50,7 @@ export function assertStatedScope(skipDirectories: readonly string[] | undefined
|
|
|
68
50
|
* cycle. They take the records their caller already holds.
|
|
69
51
|
*
|
|
70
52
|
* That is not a workaround dressed up as a rule. A compile runs several passes
|
|
71
|
-
* over one tree, and the whole
|
|
53
|
+
* over one tree, and the whole point is that they must not each answer "which
|
|
72
54
|
* files are the corpus?" for themselves. Requiring the answer to be handed in
|
|
73
55
|
* makes the sharing structural rather than remembered.
|
|
74
56
|
*
|
|
@@ -78,8 +60,35 @@ export function assertStatedScope(skipDirectories: readonly string[] | undefined
|
|
|
78
60
|
* @returns {void}
|
|
79
61
|
*/
|
|
80
62
|
export function assertSuppliedCorpus(records: readonly object[] | undefined, who: string): void;
|
|
81
|
-
|
|
82
|
-
|
|
63
|
+
/**
|
|
64
|
+
* Recursively yields every `.md` file under `rootDir`, parsed.
|
|
65
|
+
*
|
|
66
|
+
* Yields `{ frontmatter, body, description, file, absPath, bodyLine,
|
|
67
|
+
* bodyColumn }` for each match — the last from {@link parseMarkdownFile}, so a
|
|
68
|
+
* caller can report a position inside the body as a position in the file. A
|
|
69
|
+
* root that does not exist yields nothing, and a directory that cannot be read
|
|
70
|
+
* is warned about and skipped.
|
|
71
|
+
*
|
|
72
|
+
* Directory names in `skipDirectories` are ignored wherever they appear. The
|
|
73
|
+
* walk itself knows nothing about what they mean: `Templates/` is an Obsidian
|
|
74
|
+
* templater convention this repository's vault happens to use, not a property
|
|
75
|
+
* of a content tree, so it is stated by the caller rather than hard-coded.
|
|
76
|
+
*
|
|
77
|
+
* @param {string} rootDir - Root of the tree to walk.
|
|
78
|
+
* @param {object} opts
|
|
79
|
+
* @param {readonly string[]} opts.skipDirectories - Directory names to ignore.
|
|
80
|
+
* Required: the scope is the caller's to state, so two passes cannot
|
|
81
|
+
* disagree about which files are the corpus.
|
|
82
|
+
* @yields {{frontmatter: object|null, body: string, description: string,
|
|
83
|
+
* file: string, absPath: string, bodyLine?: number, bodyColumn?: number}}
|
|
84
|
+
* One entry per `.md` file found.
|
|
85
|
+
* @throws {Error} When `skipDirectories` is not stated — see
|
|
86
|
+
* {@link assertStatedScope}.
|
|
87
|
+
*/
|
|
88
|
+
export function walkMarkdownTree(rootDir: string, { skipDirectories }?: {
|
|
89
|
+
skipDirectories: readonly string[];
|
|
90
|
+
}): Generator<{
|
|
91
|
+
file: string & NonSharedBuffer;
|
|
83
92
|
absPath: string;
|
|
84
93
|
frontmatter: null;
|
|
85
94
|
body: string;
|
|
@@ -87,7 +96,7 @@ export function walkMarkdownTree(rootDir: any, { skipDirectories }?: {}): Genera
|
|
|
87
96
|
bodyLine?: undefined;
|
|
88
97
|
bodyColumn?: undefined;
|
|
89
98
|
} | {
|
|
90
|
-
file: string;
|
|
99
|
+
file: string & NonSharedBuffer;
|
|
91
100
|
absPath: string;
|
|
92
101
|
frontmatter: any;
|
|
93
102
|
body: string;
|
|
@@ -97,7 +106,7 @@ export function walkMarkdownTree(rootDir: any, { skipDirectories }?: {}): Genera
|
|
|
97
106
|
}, void, unknown>;
|
|
98
107
|
/**
|
|
99
108
|
* The template priority a note states, for a system that treats an unstated one
|
|
100
|
-
* as "not a template" rather than as an authoring error
|
|
109
|
+
* as "not a template" rather than as an authoring error.
|
|
101
110
|
*
|
|
102
111
|
* Reads exactly the positions {@link resolveTemplatePriority} reads, including
|
|
103
112
|
* the retiring `archetype` spelling, and refuses the same contradiction — so
|
|
@@ -119,7 +128,7 @@ export function statedTemplatePriority(fm: object, label: string, { block }?: {
|
|
|
119
128
|
}): number | null;
|
|
120
129
|
/**
|
|
121
130
|
* Resolve the required `templatePriority` frontmatter for an Item/Actor entry
|
|
122
|
-
* (the archetype contract
|
|
131
|
+
* (the archetype contract). The property is a nullable number that
|
|
123
132
|
* authors must state explicitly:
|
|
124
133
|
* - a number → the document is a template of that priority.
|
|
125
134
|
* - `null` → the document is not a template.
|
|
@@ -128,7 +137,7 @@ export function statedTemplatePriority(fm: object, label: string, { block }?: {
|
|
|
128
137
|
*
|
|
129
138
|
* Reads the positions {@link findTemplatePriority} lists: `data.templatePriority`
|
|
130
139
|
* first — the specified home — then the system block and the top level, and
|
|
131
|
-
* finally the retiring `archetype` spelling in the same two places
|
|
140
|
+
* finally the retiring `archetype` spelling in the same two places.
|
|
132
141
|
*
|
|
133
142
|
* @param {object} fm Parsed frontmatter.
|
|
134
143
|
* @param {string} label Human-readable context for error messages.
|
|
@@ -143,8 +152,7 @@ export function resolveTemplatePriority(fm: object, label: string, { block }?: {
|
|
|
143
152
|
}): number | undefined;
|
|
144
153
|
/**
|
|
145
154
|
* The value a document's `system.templatePriority` carries, from the required
|
|
146
|
-
* `templatePriority` frontmatter (
|
|
147
|
-
* #266 / sohl#1836).
|
|
155
|
+
* `templatePriority` frontmatter (`archetype` is the legacy spelling).
|
|
148
156
|
*
|
|
149
157
|
* A **schema field**, so the tri-state is written out in full rather than
|
|
150
158
|
* expressed by a key's presence: a number is a template at that priority, and
|
|
@@ -174,7 +182,7 @@ export function makeFilename(name: any, id: any): string;
|
|
|
174
182
|
*
|
|
175
183
|
* Content frontmatter (`img` / `portrait`) authors a single path that has to
|
|
176
184
|
* work for Foundry, the knowledgebase, and the website. **Its first segment
|
|
177
|
-
* says which package owns the file
|
|
185
|
+
* says which package owns the file**, and there are exactly three
|
|
178
186
|
* answers:
|
|
179
187
|
*
|
|
180
188
|
* | Authored path starts with | Owner | Emitted |
|
|
@@ -186,7 +194,7 @@ export function makeFilename(name: any, id: any): string;
|
|
|
186
194
|
* So `icons/relic.svg` compiles to `systems/sohl/assets/icons/relic.svg` here
|
|
187
195
|
* and to `modules/sohl-thalorna/assets/icons/relic.svg` in a module — the asset
|
|
188
196
|
* root is derived from the configuration, and is the one place `systems/sohl`
|
|
189
|
-
* is ever spelled
|
|
197
|
+
* is ever spelled. An authored
|
|
190
198
|
* `systems/sohl/assets/icons/noun/shield.svg` is left exactly as written,
|
|
191
199
|
* whichever package is compiling it.
|
|
192
200
|
*
|
|
@@ -197,13 +205,13 @@ export function makeFilename(name: any, id: any): string;
|
|
|
197
205
|
* `assets/artwork/`, so an authored `artwork/deity.webp` would have shipped
|
|
198
206
|
* unprefixed: a 404 in Foundry, reported by nothing. That a package owns its
|
|
199
207
|
* own tree is the fact; the directory names inside it are that package's
|
|
200
|
-
* business
|
|
208
|
+
* business.
|
|
201
209
|
*
|
|
202
210
|
* **Off-install addresses pass through too**, which is the same rule rather
|
|
203
211
|
* than a fourth: a URL, a `data:` URI, or a `/`-rooted path names something no
|
|
204
212
|
* package owns. See {@link addressesAnotherPackage}.
|
|
205
213
|
*
|
|
206
|
-
* **`banner:` does not follow this rule, deliberately
|
|
214
|
+
* **`banner:` does not follow this rule, deliberately.** It is not an
|
|
207
215
|
* asset path inside a Foundry install at all: it reaches no compiled document,
|
|
208
216
|
* and its only consumer is the Hugo theme, which prefixes a relative value with
|
|
209
217
|
* `images/` and joins it onto `params.cdnBaseURL`. The two fields look alike
|
|
@@ -211,7 +219,7 @@ export function makeFilename(name: any, id: any): string;
|
|
|
211
219
|
* the CDN serves — so they are documented apart rather than reconciled into one
|
|
212
220
|
* rule that would be true of neither.
|
|
213
221
|
*
|
|
214
|
-
* **Two empties, and they mean opposite things
|
|
222
|
+
* **Two empties, and they mean opposite things.** `null` — or an absent
|
|
215
223
|
* key, which reaches here as `undefined` — means _unset_: the note names no art
|
|
216
224
|
* and the caller's default applies. `""` means _blank on purpose_: the note
|
|
217
225
|
* names no art **and wants none**, so no default may replace it. Both come back
|
|
@@ -230,7 +238,7 @@ export function makeFilename(name: any, id: any): string;
|
|
|
230
238
|
* is `""` (`sohl/item-fields.mjs`), resolved from the very same shared top-level
|
|
231
239
|
* key the site emitter reads as the page title — so `title: null` stringifies
|
|
232
240
|
* into the compiled document as the literal `"null"`. One key, two destinations
|
|
233
|
-
* that disagree about what empty means; see
|
|
241
|
+
* that disagree about what empty means; see.
|
|
234
242
|
*
|
|
235
243
|
* This is translation only: the default for an unset path is domain-specific
|
|
236
244
|
* (actors default differently from items, and gear differently again), so each
|
|
@@ -241,14 +249,22 @@ export function makeFilename(name: any, id: any): string;
|
|
|
241
249
|
* `itemArt()`, which runs the path back through this function so a registry
|
|
242
250
|
* entry and a note's `img:` are spelled the same way (#7).
|
|
243
251
|
*
|
|
252
|
+
* **A package with no asset root cannot answer at all.** `assetRoot` is derived
|
|
253
|
+
* from the package kind, and a `documentation` package has none: Foundry serves
|
|
254
|
+
* no files for it. Only a compiling pass reaches here, and a documentation
|
|
255
|
+
* package runs none, so a path arriving with no root to put it under is a pass
|
|
256
|
+
* running where it should not — reported as that, rather than emitted as
|
|
257
|
+
* `null/icons/relic.svg` into a document nobody would check.
|
|
258
|
+
*
|
|
244
259
|
* @param {string | null | undefined} raw - content-relative path from frontmatter.
|
|
245
|
-
* @param {{assetRoot: string}} [config] - The resolved build configuration.
|
|
260
|
+
* @param {{assetRoot: string|null}} [config] - The resolved build configuration.
|
|
246
261
|
* Defaults to this repository's.
|
|
247
262
|
* @returns {string | null} the Foundry-relative path; `""` for a deliberate
|
|
248
263
|
* blank, and `null` when the note names no art at all.
|
|
264
|
+
* @throws {Error} When the configuration has no asset root.
|
|
249
265
|
*/
|
|
250
266
|
export function resolveImg(raw: string | null | undefined, config?: {
|
|
251
|
-
assetRoot: string;
|
|
267
|
+
assetRoot: string | null;
|
|
252
268
|
}): string | null;
|
|
253
269
|
/**
|
|
254
270
|
* Resolves the display name from frontmatter, preferring `name.full`,
|
|
@@ -263,7 +279,7 @@ export function resolveName(fm: any, defaultValue?: string): any;
|
|
|
263
279
|
* its migration shims on: a record stamped older than a shim is rewritten by it
|
|
264
280
|
* on load. Every pack once shipped `coreVersion: "14"`, which sorts *below*
|
|
265
281
|
* every v14 build and so left all shipped content permanently eligible for
|
|
266
|
-
* every v14 migration
|
|
282
|
+
* every v14 migration.
|
|
267
283
|
*
|
|
268
284
|
* **Read from the configuration, not from the shipped manifest.** It used to
|
|
269
285
|
* open `paths.packageManifest` and take `compatibility.minimum` out of it,
|
|
@@ -289,7 +305,7 @@ export function supportedCoreVersion(config?: {
|
|
|
289
305
|
/**
|
|
290
306
|
* Default `_stats` block for compiled compendium entries.
|
|
291
307
|
*
|
|
292
|
-
* Every stamped identity is configuration
|
|
308
|
+
* Every stamped identity is configuration: four compilers used to pass
|
|
293
309
|
* the same frozen `"0.6.0"` literal, and `systemId` / `lastModifiedBy` were
|
|
294
310
|
* written into this function. `coreVersion` alone is *not* configuration — it
|
|
295
311
|
* comes from {@link supportedCoreVersion}, the configured Foundry floor,
|
|
@@ -313,13 +329,12 @@ export function buildStats(systemVersion?: string, config?: {
|
|
|
313
329
|
};
|
|
314
330
|
}): object;
|
|
315
331
|
/**
|
|
316
|
-
* The `_stats` block for one pack, stamped with the system that pack is for
|
|
317
|
-
* (#48).
|
|
332
|
+
* The `_stats` block for one pack, stamped with the system that pack is for.
|
|
318
333
|
*
|
|
319
334
|
* **`systemId` travels with `systemVersion`.** They are one decision, so where
|
|
320
335
|
* one is omitted both are. Stamping a per-pack version against a package-wide
|
|
321
336
|
* id would emit `systemId: sohl, systemVersion: 1.6.3` on HM3 documents — a
|
|
322
|
-
* *plausible lie*, which is worse than
|
|
337
|
+
* *plausible lie*, which is worse than a missing value, because
|
|
323
338
|
* nothing about it looks wrong.
|
|
324
339
|
*
|
|
325
340
|
* Resolution, in order:
|
|
@@ -358,11 +373,11 @@ export function defaultStats(): object;
|
|
|
358
373
|
*
|
|
359
374
|
* Each note's pack is resolved here, once, and stored on its index entry: a
|
|
360
375
|
* UUID carries a pack name, so a repository shipping several packs of one type
|
|
361
|
-
*
|
|
376
|
+
* would otherwise address every one of them as the first. A note whose
|
|
362
377
|
* declaration is unroutable is indexed against the conventional name and left
|
|
363
378
|
* for the compile pass to report — the index has no business failing a build,
|
|
364
379
|
* and the pass fails it with a far better message. The one exception is a
|
|
365
|
-
* **retired** content type
|
|
380
|
+
* **retired** content type: this walk is the first to see every
|
|
366
381
|
* note together with its path, and unlike an unroutable declaration there is
|
|
367
382
|
* no pass that would ever claim such a note and report it.
|
|
368
383
|
*
|
|
@@ -370,9 +385,23 @@ export function defaultStats(): object;
|
|
|
370
385
|
* @param {object} [router] - The pack router. Supplied by the calling pass so
|
|
371
386
|
* the index and the compile agree about where each note landed; defaults to
|
|
372
387
|
* this repository's own.
|
|
388
|
+
* @param {object} [opts]
|
|
389
|
+
* @param {readonly string[]} [opts.skipDirectories] - Part of the options bag
|
|
390
|
+
* every corpus reader takes; the scope is already settled by `records`.
|
|
391
|
+
* @param {object} [opts.config] - The resolved build configuration; loaded when
|
|
392
|
+
* omitted.
|
|
393
|
+
* @param {readonly object[]} [opts.records] - The corpus, derived once per
|
|
394
|
+
* compile and handed in. Required: see {@link assertSuppliedCorpus}.
|
|
395
|
+
* @param {object[]} [opts.problems] - Part of the same options bag; the notes
|
|
396
|
+
* the index cannot record are collected where the corpus is derived.
|
|
373
397
|
* @returns {{byShortcode: Map, types: Set}} From `buildWikilinkIndex`.
|
|
374
398
|
*/
|
|
375
|
-
export function buildContentLinkIndex(contentBase: string, router?: object, { skipDirectories, config, records, problems }?: {
|
|
399
|
+
export function buildContentLinkIndex(contentBase: string, router?: object, { skipDirectories, config, records, problems }?: {
|
|
400
|
+
skipDirectories?: readonly string[] | undefined;
|
|
401
|
+
config?: object | undefined;
|
|
402
|
+
records?: readonly object[] | undefined;
|
|
403
|
+
problems?: object[] | undefined;
|
|
404
|
+
}): {
|
|
376
405
|
byShortcode: Map<any, any>;
|
|
377
406
|
types: Set<any>;
|
|
378
407
|
};
|
|
@@ -381,25 +410,49 @@ export function buildContentLinkIndex(contentBase: string, router?: object, { sk
|
|
|
381
410
|
* target in the content tree. Every compiler funnels through this so the
|
|
382
411
|
* diagnostic text and the leave-it-alone fallback are identical everywhere.
|
|
383
412
|
*
|
|
384
|
-
* Each report names the **file, line and column** the link sits on
|
|
413
|
+
* Each report names the **file, line and column** the link sits on, so
|
|
385
414
|
* it can be opened and fixed — and so two identical links on one note are
|
|
386
415
|
* tellable apart. That needs `file` and the note's `bodyLine` / `bodyColumn`;
|
|
387
416
|
* without them the diagnostic still reports, one field shorter, rather than
|
|
388
417
|
* inventing a position.
|
|
389
418
|
*
|
|
390
419
|
* @param {string} body - The note's markdown body, tables already expanded.
|
|
391
|
-
* @param {object} ctx
|
|
392
|
-
*
|
|
393
|
-
*
|
|
394
|
-
*
|
|
395
|
-
*
|
|
420
|
+
* @param {object} ctx
|
|
421
|
+
* @param {string} ctx.type - The source note's content type.
|
|
422
|
+
* @param {string} ctx.id - The source note's document id.
|
|
423
|
+
* @param {string} ctx.pack - The pack the note's own document lands in, which
|
|
424
|
+
* addresses a `[[#slug]]` self-link: its target is the source note itself, so
|
|
425
|
+
* it has no index entry.
|
|
426
|
+
* @param {string} ctx.docPack - The pack the note's documentation journal lands
|
|
427
|
+
* in, addressing a self-link the same way.
|
|
428
|
+
* @param {object} ctx.index - The address index every link resolves through.
|
|
429
|
+
* @param {string} ctx.name - The note, for the message.
|
|
430
|
+
* @param {string} [ctx.file] - The note's file, so a report names it.
|
|
431
|
+
* @param {number} [ctx.bodyLine] - 1-based file line of the body's first line.
|
|
432
|
+
* @param {number} [ctx.bodyColumn] - 1-based file column of the same character.
|
|
433
|
+
* @param {Array<{line: number, generated: boolean}>} [ctx.lineMap] - Which
|
|
434
|
+
* authored line each body line came from, from {@link expandNoteTables}.
|
|
396
435
|
* @returns {{markdown: string, unresolved: Array<object>}}
|
|
397
436
|
* @throws {Error} On any link that does not resolve — an unlabelled one, a
|
|
398
437
|
* target that is not an address, or an address nothing publishes. The error
|
|
399
438
|
* carries `file` and `position`, so a caller reports it in the same form
|
|
400
439
|
* rather than re-deriving one.
|
|
401
440
|
*/
|
|
402
|
-
export function convertNoteWikilinks(body: string, { type, id, pack, docPack, index, name, file, bodyLine, bodyColumn, lineMap }:
|
|
441
|
+
export function convertNoteWikilinks(body: string, { type, id, pack, docPack, index, name, file, bodyLine, bodyColumn, lineMap }: {
|
|
442
|
+
type: string;
|
|
443
|
+
id: string;
|
|
444
|
+
pack: string;
|
|
445
|
+
docPack: string;
|
|
446
|
+
index: object;
|
|
447
|
+
name: string;
|
|
448
|
+
file?: string | undefined;
|
|
449
|
+
bodyLine?: number | undefined;
|
|
450
|
+
bodyColumn?: number | undefined;
|
|
451
|
+
lineMap?: {
|
|
452
|
+
line: number;
|
|
453
|
+
generated: boolean;
|
|
454
|
+
}[] | undefined;
|
|
455
|
+
}): {
|
|
403
456
|
markdown: string;
|
|
404
457
|
unresolved: Array<object>;
|
|
405
458
|
};
|
|
@@ -409,10 +462,24 @@ export function convertNoteWikilinks(body: string, { type, id, pack, docPack, in
|
|
|
409
462
|
* a table that leaves rows tied still emits identically on every build.
|
|
410
463
|
*
|
|
411
464
|
* @param {string} contentBase - Root of the content tree.
|
|
465
|
+
* @param {object} [opts]
|
|
466
|
+
* @param {readonly string[]} [opts.skipDirectories] - Part of the options bag
|
|
467
|
+
* every corpus reader takes; the scope is already settled by `records`.
|
|
468
|
+
* @param {object} [opts.config] - The resolved build configuration; loaded when
|
|
469
|
+
* omitted.
|
|
470
|
+
* @param {readonly object[]} [opts.records] - The corpus, derived once per
|
|
471
|
+
* compile and handed in. Required: see {@link assertSuppliedCorpus}.
|
|
472
|
+
* @param {object[]} [opts.problems] - Part of the same options bag; the notes
|
|
473
|
+
* the walk cannot read are collected where the corpus is derived.
|
|
412
474
|
* @returns {Array<{fm: object, path: string, tld: string, folder: string,
|
|
413
475
|
* absPath: string}>}
|
|
414
476
|
*/
|
|
415
|
-
export function collectContentDocs(contentBase: string, { skipDirectories, config, records, problems }?: {
|
|
477
|
+
export function collectContentDocs(contentBase: string, { skipDirectories, config, records, problems }?: {
|
|
478
|
+
skipDirectories?: readonly string[] | undefined;
|
|
479
|
+
config?: object | undefined;
|
|
480
|
+
records?: readonly object[] | undefined;
|
|
481
|
+
problems?: object[] | undefined;
|
|
482
|
+
}): Array<{
|
|
416
483
|
fm: object;
|
|
417
484
|
path: string;
|
|
418
485
|
tld: string;
|
|
@@ -426,7 +493,7 @@ export function collectContentDocs(contentBase: string, { skipDirectories, confi
|
|
|
426
493
|
* A table searches the whole tree, which is one package's notes and nothing
|
|
427
494
|
* else — so there is no longer a package to scope on. It used to filter, back
|
|
428
495
|
* when a tree could hold several packages' notes and `package:` said which was
|
|
429
|
-
* which; that field is retired and the filter with it
|
|
496
|
+
* which; that field is retired and the filter with it.
|
|
430
497
|
*
|
|
431
498
|
* @param {string} body - The note's markdown body.
|
|
432
499
|
* @param {object} ctx
|
|
@@ -436,10 +503,14 @@ export function collectContentDocs(contentBase: string, { skipDirectories, confi
|
|
|
436
503
|
* query's `this` reads. Its entry in `docs` supplies the path as well.
|
|
437
504
|
* @param {number} [ctx.bodyLine] - 1-based file line of the body's first line,
|
|
438
505
|
* so a failing directive can be reported at its position in the file.
|
|
506
|
+
* @param {object[]} [ctx.sqlTables] - This note's prepared `sql` results, in
|
|
507
|
+
* document order, from
|
|
508
|
+
* {@link module:engine/sql-tables.prepareSqlTables}. An `sql` directive with
|
|
509
|
+
* no prepared result fails the note: nothing here runs a query.
|
|
439
510
|
* @returns {{markdown: string, lineMap: Array<{line: number,
|
|
440
511
|
* generated: boolean}>}} The body with every table expanded, and where each
|
|
441
512
|
* emitted line came from — which is what lets a diagnostic about the
|
|
442
|
-
* expanded body name an authored position
|
|
513
|
+
* expanded body name an authored position.
|
|
443
514
|
* @throws {Error} When a query is malformed or unsupported — the note fails to
|
|
444
515
|
* compile rather than shipping a table-shaped hole. The error carries
|
|
445
516
|
* `position`, the directive's own line.
|
|
@@ -449,6 +520,7 @@ export function expandNoteTables(body: string, { docs, name, fm, bodyLine, sqlTa
|
|
|
449
520
|
name: string;
|
|
450
521
|
fm?: object | undefined;
|
|
451
522
|
bodyLine?: number | undefined;
|
|
523
|
+
sqlTables?: object[] | undefined;
|
|
452
524
|
}): {
|
|
453
525
|
markdown: string;
|
|
454
526
|
lineMap: Array<{
|
|
@@ -468,7 +540,7 @@ export function folderFilename(name: any, id: any): string;
|
|
|
468
540
|
* `html: true` is long-standing and load-bearing — notes carry raw blocks — and
|
|
469
541
|
* it is also why {@link module:engine/content-icons} exists rather than an
|
|
470
542
|
* instruction to write `<i class="fa-solid …">` by hand: that would render on
|
|
471
|
-
* the two HTML surfaces and be silently dropped by the third
|
|
543
|
+
* the two HTML surfaces and be silently dropped by the third.
|
|
472
544
|
*/
|
|
473
545
|
export const md: import("markdown-it").MarkdownIt;
|
|
474
546
|
export { slugify } from "./content-slug.mjs";
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* The file a homepage is written to, relative to the package's site root.
|
|
3
3
|
*
|
|
4
4
|
* Its **address**, flat at the package root, and stated in the page's own `url`
|
|
5
|
-
* — the same separation every other page has
|
|
5
|
+
* — the same separation every other page has, where the directory
|
|
6
6
|
* decides the Hugo section and the front matter decides the URL. Flat rather
|
|
7
7
|
* than inside a `homepage/` section directory, because a homepage is not one of
|
|
8
8
|
* a kind: a section holding exactly one page would publish a landing at
|
|
@@ -45,8 +45,8 @@ export function isHomepage(fm: object | null | undefined): boolean;
|
|
|
45
45
|
* **A refused field must be one the note *wrote*.** `resolveNoteId` fills
|
|
46
46
|
* `fm.id` **in place** so every downstream reader sees one derived value —
|
|
47
47
|
* deliberately, and documented as such — and this ran over the same object, so
|
|
48
|
-
* a homepage that authors no `id` was told to delete one that is not there
|
|
49
|
-
*
|
|
48
|
+
* a homepage that authors no `id` was told to delete one that is not there.
|
|
49
|
+
* Since the caller already owns the raw note text, it also answers
|
|
50
50
|
* which keys the note actually declared; without an answer every key in `fm`
|
|
51
51
|
* counts, which is the old behaviour and right for a caller holding authored
|
|
52
52
|
* frontmatter only.
|
|
@@ -70,19 +70,17 @@ export function checkHomepageAddressFields(fm: object | null | undefined, { isAu
|
|
|
70
70
|
message: string;
|
|
71
71
|
}>;
|
|
72
72
|
/**
|
|
73
|
-
* Require exactly one homepage note in a content tree
|
|
73
|
+
* Require exactly one homepage note in a content tree.
|
|
74
74
|
*
|
|
75
75
|
* "Exactly one" is two rules, and they are **one severity** because they are
|
|
76
76
|
* one defect: a package whose front page is not the page a person chose.
|
|
77
77
|
*
|
|
78
78
|
* - _None_ and the package serves nothing at `/<package>/`. That is the failure
|
|
79
|
-
*
|
|
79
|
+
* this exists to prevent, and it is silent — the site build reports `wrote 0
|
|
80
80
|
* homepage(s)` and exits 0.
|
|
81
81
|
* - _Two_ and it serves a page nobody chose. **This is a cardinality rule, and
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
* rule enforced it as a side effect. A homepage is written at its own address
|
|
85
|
-
* now, so two of them publish two pages and collide over nothing; the
|
|
82
|
+
* only that.** A homepage is written at its own address, so two of them
|
|
83
|
+
* publish two pages and collide over nothing; the
|
|
86
84
|
* duplicate-address check catches only the pair that happen to share a
|
|
87
85
|
* shortcode, and says nothing at all about a `homepage-root` beside a
|
|
88
86
|
* `homepage-front`. Which of the two the redirect at `/<package>/` should
|
|
@@ -153,17 +151,17 @@ export function homepageTitle(fm: object | null | undefined, config: object): st
|
|
|
153
151
|
*
|
|
154
152
|
* The note's own, plus the derived values every emitted page carries: the
|
|
155
153
|
* resolved `title`, the package the build derived — no note declares one
|
|
156
|
-
* (`package:` is retired
|
|
154
|
+
* (`package:` is retired) and the theme's breadcrumb partial reads
|
|
157
155
|
* `.Params.package` — and its **address**.
|
|
158
156
|
*
|
|
159
157
|
* The address is stated as `url` for the same reason every other page states
|
|
160
|
-
* one
|
|
158
|
+
* one: Hugo publishes a page where its file sits unless told otherwise,
|
|
161
159
|
* and a homepage's file sits at the package's site root. `slug` is written
|
|
162
160
|
* beside it because it is the last segment of that address and Hugo's own key
|
|
163
161
|
* for one; it decides nothing while `url` is present, but a page carrying only
|
|
164
162
|
* `url` would report a slug Hugo had inferred from the filename.
|
|
165
163
|
*
|
|
166
|
-
* **Site-root relative, and so carrying no package base
|
|
164
|
+
* **Site-root relative, and so carrying no package base**, exactly as
|
|
167
165
|
* `pageFrontmatter` states a content page's: Hugo resolves a `url`
|
|
168
166
|
* against `baseURL`, whose path is already where the package is served, so a
|
|
169
167
|
* stated base was written twice and published the landing at
|
|
@@ -172,7 +170,7 @@ export function homepageTitle(fm: object | null | undefined, config: object): st
|
|
|
172
170
|
*
|
|
173
171
|
* An authored `aliases` is dropped for the same reason it is on every other
|
|
174
172
|
* page: Hugo reads it as URL redirects, so passing it through would publish a
|
|
175
|
-
* redirect stub at each one. The field is retired
|
|
173
|
+
* redirect stub at each one. The field is retired and refused before a
|
|
176
174
|
* build reaches here, which makes this a guard rather than a working path.
|
|
177
175
|
*
|
|
178
176
|
* @param {object} fm - The note's frontmatter.
|
|
@@ -252,14 +250,14 @@ export const HOMEPAGE_FIELDS: readonly import("./field-spec.mjs").FieldSpec[];
|
|
|
252
250
|
*/
|
|
253
251
|
export const HOMEPAGE_SHORTCODE: string;
|
|
254
252
|
/**
|
|
255
|
-
* The top-level field a homepage refuses, and what it would decide
|
|
253
|
+
* The top-level field a homepage refuses, and what it would decide.
|
|
256
254
|
*
|
|
257
|
-
* **One field
|
|
255
|
+
* **One field rather than three.** `name` and `shortcode` are
|
|
258
256
|
* refused because a page's URL derived from `name.full` while a homepage's
|
|
259
257
|
* destination was fixed, so the address a `shortcode` computed named a page the
|
|
260
|
-
* site build never wrote. A page's URL is its address now
|
|
258
|
+
* site build never wrote. A page's URL is its address now and a homepage
|
|
261
259
|
* publishes at its own, so both fields decide exactly what they decide
|
|
262
|
-
* everywhere else and are permitted
|
|
260
|
+
* everywhere else and are permitted.
|
|
263
261
|
*
|
|
264
262
|
* `id` is untouched by that, and stays: it is the Foundry document id a
|
|
265
263
|
* compendium UUID is built from, and a homepage compiles into no document.
|
|
@@ -272,7 +270,7 @@ export const HOMEPAGE_SHORTCODE: string;
|
|
|
272
270
|
* package-build release.
|
|
273
271
|
*
|
|
274
272
|
* `aliases` is deliberately not in the class: it is a **retired** field, refused
|
|
275
|
-
* on every note whatever its type
|
|
273
|
+
* on every note whatever its type, so it is answered there rather than
|
|
276
274
|
* here.
|
|
277
275
|
*
|
|
278
276
|
* @type {ReadonlyMap<string, string>}
|
package/types/engine/ids.d.mts
CHANGED
|
@@ -56,12 +56,12 @@ export function renamedTypeMessage(retired: string, current: string, where?: str
|
|
|
56
56
|
* Item types are the open set — a new one is added whenever the system grows a
|
|
57
57
|
* document type — so they are the **default** rather than an enumerated list. A
|
|
58
58
|
* hand-maintained list is what made an entire content directory silently
|
|
59
|
-
* unlinkable once
|
|
59
|
+
* unlinkable once; nothing to maintain, nothing to forget.
|
|
60
60
|
*
|
|
61
61
|
* The `docType` is the authority: it is a property of the *content type* and
|
|
62
62
|
* holds however a repository names or splits its packs. The `pack` is the
|
|
63
63
|
* conventional name only — a repository may rename its packs, or ship several
|
|
64
|
-
* of one type
|
|
64
|
+
* of one type, in which case the pack a particular note's document
|
|
65
65
|
* lands in comes from `engine/pack-router.mjs` and is passed to
|
|
66
66
|
* {@link compendiumUuid} explicitly. This module stays free of the
|
|
67
67
|
* configuration so the link resolver above it can stay pure.
|
|
@@ -89,8 +89,8 @@ export function packForType(type: string): {
|
|
|
89
89
|
* @param {string} id - The document's id.
|
|
90
90
|
* @param {string} [packName] - The pack the document actually landed in, from
|
|
91
91
|
* the pack router. Supplied wherever the note is known, because a repository
|
|
92
|
-
* may ship several packs of one type and a UUID carries the pack name
|
|
93
|
-
*
|
|
92
|
+
* may ship several packs of one type and a UUID carries the pack name.
|
|
93
|
+
* Omitted only where there is no note to route — the conventional
|
|
94
94
|
* name from {@link packForType} then stands in.
|
|
95
95
|
* @returns {string} `Compendium.<packageId>.<pack>.<DocumentType>.<id>`
|
|
96
96
|
*/
|
|
@@ -105,8 +105,8 @@ export function compendiumUuid(packageId: string, type: string, id: string, pack
|
|
|
105
105
|
*/
|
|
106
106
|
export function pageUuid(entryUuid: string, pageId: string): string;
|
|
107
107
|
/**
|
|
108
|
-
* Every content type that compiles into a Foundry `Scene` — a **map note
|
|
109
|
-
*
|
|
108
|
+
* Every content type that compiles into a Foundry `Scene` — a **map note**.
|
|
109
|
+
* The three differ only in derived canvas defaults, which is the map
|
|
110
110
|
* compiler's business; everything else treats them alike.
|
|
111
111
|
*
|
|
112
112
|
* Declared in this leaf module because several passes that must not depend on
|
|
@@ -120,7 +120,7 @@ export const MAP_TYPES: ReadonlySet<string>;
|
|
|
120
120
|
/**
|
|
121
121
|
* The map subTypes, which differ only in the canvas defaults derived for them.
|
|
122
122
|
*
|
|
123
|
-
*
|
|
123
|
+
* As three *types* they would cost three entries in the pack
|
|
124
124
|
* router, three in the claims set and three in every consumer's section config
|
|
125
125
|
* — for one idea that the specification had always described as one type.
|
|
126
126
|
*
|
|
@@ -137,8 +137,8 @@ export const MAP_SUBTYPES: readonly string[];
|
|
|
137
137
|
* addressed as `<type>` and `doc<type>`. These are one, so there is no
|
|
138
138
|
* `docplace` and nothing synthesizes one.
|
|
139
139
|
*
|
|
140
|
-
* `doc` was the only member until
|
|
141
|
-
* the published content format and
|
|
140
|
+
* `doc` was the only member until. `place`, `lore` and `scenario` are in
|
|
141
|
+
* the published content format and are declared for validation, but
|
|
142
142
|
* nothing routed them: a note of one lint-ed clean and then compiled into
|
|
143
143
|
* nothing, because {@link PACK_BY_TYPE} did not name it and the open-set
|
|
144
144
|
* default sent it to the items pack. `sohl-thalorna` could not compile a single
|
|
@@ -157,7 +157,7 @@ export const JOURNAL_TYPES: ReadonlySet<string>;
|
|
|
157
157
|
* building and not of the content: the same notes compiled by a different
|
|
158
158
|
* repository belong to a different package. Baking the package into these
|
|
159
159
|
* values is what made every link emitted by `sohl-thalorna` address the `sohl`
|
|
160
|
-
* system
|
|
160
|
+
* system — correct here only by coincidence.
|
|
161
161
|
*
|
|
162
162
|
* @type {Readonly<Record<string, {pack: string, docType: string}>>}
|
|
163
163
|
*/
|
|
@@ -169,7 +169,7 @@ export const PACK_BY_TYPE: Readonly<Record<string, {
|
|
|
169
169
|
* Content types that no longer exist, and what replaced each one.
|
|
170
170
|
*
|
|
171
171
|
* `character` and `creature` were retired in favour of the single `being` they
|
|
172
|
-
* had always compiled into
|
|
172
|
+
* had always compiled into. They are recorded here rather than
|
|
173
173
|
* simply deleted because deleting them is the one change that fails *quietly*:
|
|
174
174
|
* every type not named in {@link PACK_BY_TYPE} falls through to the open item
|
|
175
175
|
* set below, so a note or a link left on the old spelling would be routed to
|
|
@@ -193,7 +193,7 @@ export const RETIRED_TYPES: Readonly<Record<string, string>>;
|
|
|
193
193
|
* old one compiles into exactly the document it always did: refusing it would
|
|
194
194
|
* fail a build over a note that is not wrong.
|
|
195
195
|
*
|
|
196
|
-
* So these retire in the three steps `package:` took
|
|
196
|
+
* So these retire in the three steps `package:` took, and this table is
|
|
197
197
|
* the **first**: both spellings resolve, the current one is canonical, and the
|
|
198
198
|
* retired one is *reported* — never refused. The sweep of the content trees and
|
|
199
199
|
* the refusal come after, once no tree writes the old name. That is the same
|
|
@@ -201,7 +201,7 @@ export const RETIRED_TYPES: Readonly<Record<string, string>>;
|
|
|
201
201
|
* reason: a consumer must be able to adopt the new toolchain before its content
|
|
202
202
|
* moves, and there are some 31,000 references to move.
|
|
203
203
|
*
|
|
204
|
-
* **Why these three, and why
|
|
204
|
+
* **Why these three, and why this way round.** The specification renamed
|
|
205
205
|
* `armorgear`, `concoctiongear` and `projectilegear` to `armor`, `concoction`
|
|
206
206
|
* and `projectile`, on the argument that the suffix named the *SoHL document
|
|
207
207
|
* subtype* a note compiled into rather than the thing the note is about. That
|
|
@@ -6,9 +6,9 @@
|
|
|
6
6
|
* the machine that built the index, would differ between two checkouts of the
|
|
7
7
|
* same tree, and would put someone's home directory in a published artifact. So
|
|
8
8
|
* every pass that reads the index and then needs to open a note has to compose
|
|
9
|
-
* the absolute form, and each
|
|
9
|
+
* the absolute form, and each converted reader had written its
|
|
10
10
|
* own `path.join(base, ...record.file.path.split("/"))`. Four copies of one
|
|
11
|
-
* rule is what
|
|
11
|
+
* rule is what this exists to remove, so here it is once.
|
|
12
12
|
*
|
|
13
13
|
* The split is on `"/"` rather than `path.sep` because the recorded path is
|
|
14
14
|
* always POSIX — that is what makes the index identical on every platform.
|
|
@@ -54,7 +54,7 @@ export function isNoteRecord(record: Record<string, any>): boolean;
|
|
|
54
54
|
* carry itself.
|
|
55
55
|
*
|
|
56
56
|
* `package` is the note's distribution unit — the configured `contentPackage`,
|
|
57
|
-
* since a note declaring its own is a hard error
|
|
57
|
+
* since a note declaring its own is a hard error — and it matches what
|
|
58
58
|
* the content-table expander puts on the same field, so a query reads the same
|
|
59
59
|
* value from either. `file` namespaces the note's place in the tree, again
|
|
60
60
|
* matching the expander's `file.*`.
|
package/types/engine/index.d.mts
CHANGED
|
@@ -11,6 +11,7 @@ export * as contentPackage from "./content-package.mjs";
|
|
|
11
11
|
export * as notePackage from "./note-package.mjs";
|
|
12
12
|
export * as retiredFields from "./retired-fields.mjs";
|
|
13
13
|
export * as runtimeOnlyFields from "./runtime-only-fields.mjs";
|
|
14
|
+
export * as derivedFields from "./derived-fields.mjs";
|
|
14
15
|
export * as homepage from "./homepage.mjs";
|
|
15
16
|
export * as noteSchemas from "./note-schemas.mjs";
|
|
16
17
|
export * as noteVocabulary from "./note-vocabulary.mjs";
|
|
@@ -27,6 +28,7 @@ export * as siteBuild from "./site-build.mjs";
|
|
|
27
28
|
export * as contentLint from "./content-lint.mjs";
|
|
28
29
|
export * as contentCharset from "./content-charset.mjs";
|
|
29
30
|
export * as contentIcons from "./content-icons.mjs";
|
|
31
|
+
export * as contentHtml from "./content-html.mjs";
|
|
30
32
|
export * as contentLinks from "./content-links.mjs";
|
|
31
33
|
export * as webWikilinks from "./web-wikilinks.mjs";
|
|
32
34
|
export * as contentTables from "./content-tables.mjs";
|
|
@@ -37,6 +39,10 @@ export * as itemDocs from "./item-docs.mjs";
|
|
|
37
39
|
export * as wikilinks from "./wikilinks.mjs";
|
|
38
40
|
export * as wikilinkSyntax from "./wikilink-syntax.mjs";
|
|
39
41
|
export * as siteIndex from "./site-index.mjs";
|
|
42
|
+
export * as pdfToc from "./pdf-toc.mjs";
|
|
43
|
+
export * as pdfRender from "./pdf-render.mjs";
|
|
44
|
+
export * as pdfFonts from "./pdf-fonts.mjs";
|
|
45
|
+
export * as pdfBuild from "./pdf-build.mjs";
|
|
40
46
|
export * as baseCompiler from "./base-compiler.mjs";
|
|
41
47
|
export * as journals from "./journals.mjs";
|
|
42
48
|
export * as macros from "./macros.mjs";
|