@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
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*
|
|
9
9
|
* **Only for a field that declares a `legacyKey`.** Every other field's
|
|
10
10
|
* in-block position is simply where it lives; reporting those would put a
|
|
11
|
-
* finding on every field of every note in every tree, which is
|
|
11
|
+
* finding on every field of every note in every tree, which is the corpus
|
|
12
12
|
* migration rather than a signal anyone could act on.
|
|
13
13
|
*
|
|
14
14
|
* @param {FieldSpec} field - The declaration.
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
export function readsLegacyKey(field: FieldSpec, from: import("./system-block.mjs").FieldSource): boolean;
|
|
20
20
|
/**
|
|
21
21
|
* Whether a resolution read a field from the top-level key `data:` gathered it
|
|
22
|
-
* off — the shared level's retiring position
|
|
22
|
+
* off — the shared level's retiring position.
|
|
23
23
|
*
|
|
24
24
|
* {@link readsLegacyKey}'s sibling, and the same signal: a finding here counts
|
|
25
25
|
* one note still on the pre-`data:` spelling, so the sweep has something to
|
|
@@ -42,7 +42,7 @@ export function readsRetiredTopLevel(field: FieldSpec, from: import("./system-bl
|
|
|
42
42
|
*
|
|
43
43
|
* The *position* is resolved by {@link resolveFieldValue} — `<system>.system`
|
|
44
44
|
* first, then the legacy in-block key, then the declared shared source, then
|
|
45
|
-
* the default
|
|
45
|
+
* the default. The **coercion** is applied here, once, wherever the value
|
|
46
46
|
* came from: a field's `read` is a statement about the field, not about where
|
|
47
47
|
* an author happened to write it, so `weight: "7"` reads as `7` at every one of
|
|
48
48
|
* those positions.
|
|
@@ -54,12 +54,12 @@ export function readsRetiredTopLevel(field: FieldSpec, from: import("./system-bl
|
|
|
54
54
|
* against. The default is the one block every existing tree authors; a
|
|
55
55
|
* second system passes its own.
|
|
56
56
|
* @param {(field: FieldSpec) => void} [options.onLegacyKey] - Called with each
|
|
57
|
-
* field read from the position it is being swept off
|
|
57
|
+
* field read from the position it is being swept off. A callback
|
|
58
58
|
* rather than a returned list because the caller is a compiler, which already
|
|
59
59
|
* knows the note and how to locate a key in it; this module knows neither and
|
|
60
60
|
* would have to invent a finding shape to say so.
|
|
61
61
|
* @param {(field: FieldSpec) => void} [options.onRetiredTopLevel] - Called with
|
|
62
|
-
* each field read from the top-level key `data:` gathered it off
|
|
62
|
+
* each field read from the top-level key `data:` gathered it off. The
|
|
63
63
|
* shared level's counterpart to `onLegacyKey`, and a separate callback
|
|
64
64
|
* because it is a separate position: a note may have moved one of the two and
|
|
65
65
|
* not the other, and a caller that conflated them would tell its author to
|
|
@@ -78,7 +78,7 @@ export function readField(field: FieldSpec, fm: object, options?: {
|
|
|
78
78
|
* every caller wants. A builder has one further question — *should the key be
|
|
79
79
|
* written at all* — and it cannot be answered from the value: `null` from a
|
|
80
80
|
* note and `null` from a declared default are the same value and opposite
|
|
81
|
-
* facts
|
|
81
|
+
* facts.
|
|
82
82
|
*
|
|
83
83
|
* So the position rides back beside the value, resolved **once**. The
|
|
84
84
|
* alternative is a builder that calls {@link resolveFieldValue} for the source
|
|
@@ -111,7 +111,7 @@ export function readFieldEntry(field: FieldSpec, fm: object, { block, onLegacyKe
|
|
|
111
111
|
* The question {@link FieldSpec.omitWhenAbsent} turns on, asked of the
|
|
112
112
|
* *position* rather than of the value — which cannot answer it, since a
|
|
113
113
|
* declared `default: null` and an authored `null` are indistinguishable once
|
|
114
|
-
* the value is in hand
|
|
114
|
+
* the value is in hand.
|
|
115
115
|
*
|
|
116
116
|
* `undefined` counts as absent whatever position reported it, because writing
|
|
117
117
|
* the key then emits a value `JSON.stringify` drops — the key present in the
|
|
@@ -139,10 +139,10 @@ export function isAuthored(from: import("./system-block.mjs").FieldSource, value
|
|
|
139
139
|
* systems declare the same shared source and different destinations.
|
|
140
140
|
* @param {(field: FieldSpec) => void} [options.onLegacyKey] - Passed through to
|
|
141
141
|
* {@link readField}: called with each field the note authored at the position
|
|
142
|
-
* it is being swept off
|
|
142
|
+
* it is being swept off.
|
|
143
143
|
* @param {(field: FieldSpec) => void} [options.onRetiredTopLevel] - Passed
|
|
144
144
|
* through to {@link readField}: called with each field the note authored at
|
|
145
|
-
* the top-level key `data:` gathered it off
|
|
145
|
+
* the top-level key `data:` gathered it off.
|
|
146
146
|
* @returns {(fm: object) => object} A `system`-block builder.
|
|
147
147
|
*/
|
|
148
148
|
export function buildFromFields(fields: readonly FieldSpec[], { block, onLegacyKey, onRetiredTopLevel }?: {
|
|
@@ -166,8 +166,8 @@ export function authoredFields(fields: readonly FieldSpec[]): FieldSpec[];
|
|
|
166
166
|
* The fields of a declaration a note may **never** write.
|
|
167
167
|
*
|
|
168
168
|
* The complement of {@link authoredFields} in the direction that matters: those
|
|
169
|
-
* are the fields an author may write, these are the ones authoring is an error
|
|
170
|
-
*
|
|
169
|
+
* are the fields an author may write, these are the ones authoring is an error.
|
|
170
|
+
* Everything else in a declaration — a constant, a derived value — is
|
|
171
171
|
* simply not authored, which is a statement about the *builder* rather than
|
|
172
172
|
* about the author, and says nothing about what happens if a note writes the
|
|
173
173
|
* path anyway.
|
|
@@ -179,19 +179,19 @@ export function runtimeOnlyFields(fields: readonly FieldSpec[]): FieldSpec[];
|
|
|
179
179
|
/**
|
|
180
180
|
* @typedef {object} FieldSpec
|
|
181
181
|
* @property {string} to - Dotted path in the emitted `system` block — and,
|
|
182
|
-
*
|
|
182
|
+
* the path a note authors the field at directly:
|
|
183
183
|
* `<system>.system.<to>`.
|
|
184
184
|
* @property {string} [name] - The **shared, top-level property this field draws
|
|
185
185
|
* from** when the note authors no value at `<system>.system.<to>`. Dotted for
|
|
186
186
|
* a path into a shared container (`data.portrait`), which is now the ordinary
|
|
187
|
-
* case: `data:`
|
|
187
|
+
* case: `data:` puts every type-specific fact under one.
|
|
188
188
|
*
|
|
189
|
-
*
|
|
189
|
+
* Read as "frontmatter key under `sohl:`", that meaning is the
|
|
190
190
|
* degenerate case where the shared source and the system destination happen
|
|
191
191
|
* to share a name. They constantly do not — one shared `data.portrait` feeds
|
|
192
192
|
* `sohl.system.portrait` *and* `hm3.system.bioImage` — so the source is
|
|
193
|
-
* declared rather than matched by spelling
|
|
194
|
-
* still read, second, until
|
|
193
|
+
* declared rather than matched by spelling. The in-block position is
|
|
194
|
+
* still read, second, until the corpus moves off it — keyed on
|
|
195
195
|
* `legacyKey` where the two spellings differ.
|
|
196
196
|
*
|
|
197
197
|
* Absent means the value is not authored at all — see `value`.
|
|
@@ -199,8 +199,8 @@ export function runtimeOnlyFields(fields: readonly FieldSpec[]): FieldSpec[];
|
|
|
199
199
|
* the system block** — the second position of the resolution order — when
|
|
200
200
|
* that is not `name`. Absent, the position is keyed on `name`.
|
|
201
201
|
*
|
|
202
|
-
*
|
|
203
|
-
* shared source and its in-block key were the same word. `data:`
|
|
202
|
+
* As one property the two would hold only while a field's
|
|
203
|
+
* shared source and its in-block key were the same word. `data:` ended
|
|
204
204
|
* that: a shared source is a path into a container, so `data.species` and
|
|
205
205
|
* `species` name two different places and no single value reached both.
|
|
206
206
|
* `name: "species"` could not see `data.species`; `name: "data.species"`
|
|
@@ -216,7 +216,7 @@ export function runtimeOnlyFields(fields: readonly FieldSpec[]): FieldSpec[];
|
|
|
216
216
|
* @property {string} [topLevelMeans] - **What the note's top-level key of this
|
|
217
217
|
* name means instead** — declared only where it means something else, and
|
|
218
218
|
* stating it removes the shared top-level position from this field's
|
|
219
|
-
* resolution order
|
|
219
|
+
* resolution order.
|
|
220
220
|
*
|
|
221
221
|
* A field's `name` doubles as its identity and as the shared property it
|
|
222
222
|
* draws from, which is right wherever the two levels state the same quantity
|
|
@@ -243,7 +243,7 @@ export function runtimeOnlyFields(fields: readonly FieldSpec[]): FieldSpec[];
|
|
|
243
243
|
* if the two positions hold unrelated quantities then the *in-block* position
|
|
244
244
|
* is not the note-level field either, so a check about the note-level field
|
|
245
245
|
* reads past it. `engine/frontmatter-lint.mjs` resolves that through
|
|
246
|
-
* `collidingBlockKeys`.
|
|
246
|
+
* `collidingBlockKeys`. Reading it for the emitted field alone is
|
|
247
247
|
* how an affiliation's office style came to answer for its page heading.
|
|
248
248
|
* @property {string} [shape] - Human-readable shape, for documentation. Comes
|
|
249
249
|
* paired with `read` from one of the coercion constants below.
|
|
@@ -259,10 +259,9 @@ export function runtimeOnlyFields(fields: readonly FieldSpec[]): FieldSpec[];
|
|
|
259
259
|
* third step of {@link module:engine/system-block.resolveFieldValue}'s order,
|
|
260
260
|
* so the value resolves whichever region carries it. What it tells the
|
|
261
261
|
* author-facing surfaces is which of the two is the field's *home*, so a
|
|
262
|
-
* message about it names `img` rather than sending an author to `sohl.img
|
|
263
|
-
* (#142).
|
|
262
|
+
* message about it names `img` rather than sending an author to `sohl.img`.
|
|
264
263
|
* @property {"string"|"number"|"boolean"|"list"|"map"} [kind] - The value's
|
|
265
|
-
* shape, for the frontmatter linter
|
|
264
|
+
* shape, for the frontmatter linter. Distinct from `shape`, which is
|
|
266
265
|
* prose for a reader, and from `read`, which is what the compiler does: a
|
|
267
266
|
* field may declare `kind` without changing a byte of what it emits, and
|
|
268
267
|
* several do — `weight` is coerced leniently but is still a number, and
|
|
@@ -275,7 +274,7 @@ export function runtimeOnlyFields(fields: readonly FieldSpec[]): FieldSpec[];
|
|
|
275
274
|
* @property {any|((fm: object) => any)} [value] - For a field with no `name`:
|
|
276
275
|
* the constant, or a function deriving it from the frontmatter.
|
|
277
276
|
* @property {boolean} [omitWhenAbsent] - **The key is left out entirely when
|
|
278
|
-
* the note does not carry the field
|
|
277
|
+
* the note does not carry the field**, rather than written from a
|
|
279
278
|
* declared default.
|
|
280
279
|
*
|
|
281
280
|
* Every other field answers absence with a value: an unauthored `weight` is
|
|
@@ -310,7 +309,7 @@ export function runtimeOnlyFields(fields: readonly FieldSpec[]): FieldSpec[];
|
|
|
310
309
|
* which the generated reference states in the field's own row.
|
|
311
310
|
* @property {string} [runtimeOnly] - **What the field holds once play has
|
|
312
311
|
* started** — declared on a field the *document* writes for itself, which no
|
|
313
|
-
* note may author
|
|
312
|
+
* note may author.
|
|
314
313
|
*
|
|
315
314
|
* A schema declares plenty of fields a compiled document has no business
|
|
316
315
|
* carrying: an affliction's `onsetDate` is the world time its onset fired
|
|
@@ -404,7 +403,7 @@ export const BLANK_IS_DEFAULT: Readonly<{
|
|
|
404
403
|
export type FieldSpec = {
|
|
405
404
|
/**
|
|
406
405
|
* - Dotted path in the emitted `system` block — and,
|
|
407
|
-
*
|
|
406
|
+
* the path a note authors the field at directly:
|
|
408
407
|
* `<system>.system.<to>`.
|
|
409
408
|
*/
|
|
410
409
|
to: string;
|
|
@@ -412,14 +411,14 @@ export type FieldSpec = {
|
|
|
412
411
|
* - The **shared, top-level property this field draws
|
|
413
412
|
* from** when the note authors no value at `<system>.system.<to>`. Dotted for
|
|
414
413
|
* a path into a shared container (`data.portrait`), which is now the ordinary
|
|
415
|
-
* case: `data:`
|
|
414
|
+
* case: `data:` puts every type-specific fact under one.
|
|
416
415
|
*
|
|
417
|
-
*
|
|
416
|
+
* Read as "frontmatter key under `sohl:`", that meaning is the
|
|
418
417
|
* degenerate case where the shared source and the system destination happen
|
|
419
418
|
* to share a name. They constantly do not — one shared `data.portrait` feeds
|
|
420
419
|
* `sohl.system.portrait` *and* `hm3.system.bioImage` — so the source is
|
|
421
|
-
* declared rather than matched by spelling
|
|
422
|
-
* still read, second, until
|
|
420
|
+
* declared rather than matched by spelling. The in-block position is
|
|
421
|
+
* still read, second, until the corpus moves off it — keyed on
|
|
423
422
|
* `legacyKey` where the two spellings differ.
|
|
424
423
|
*
|
|
425
424
|
* Absent means the value is not authored at all — see `value`.
|
|
@@ -430,8 +429,8 @@ export type FieldSpec = {
|
|
|
430
429
|
* the system block** — the second position of the resolution order — when
|
|
431
430
|
* that is not `name`. Absent, the position is keyed on `name`.
|
|
432
431
|
*
|
|
433
|
-
*
|
|
434
|
-
* shared source and its in-block key were the same word. `data:`
|
|
432
|
+
* As one property the two would hold only while a field's
|
|
433
|
+
* shared source and its in-block key were the same word. `data:` ended
|
|
435
434
|
* that: a shared source is a path into a container, so `data.species` and
|
|
436
435
|
* `species` name two different places and no single value reached both.
|
|
437
436
|
* `name: "species"` could not see `data.species`; `name: "data.species"`
|
|
@@ -450,7 +449,7 @@ export type FieldSpec = {
|
|
|
450
449
|
* - **What the note's top-level key of this
|
|
451
450
|
* name means instead** — declared only where it means something else, and
|
|
452
451
|
* stating it removes the shared top-level position from this field's
|
|
453
|
-
* resolution order
|
|
452
|
+
* resolution order.
|
|
454
453
|
*
|
|
455
454
|
* A field's `name` doubles as its identity and as the shared property it
|
|
456
455
|
* draws from, which is right wherever the two levels state the same quantity
|
|
@@ -477,7 +476,7 @@ export type FieldSpec = {
|
|
|
477
476
|
* if the two positions hold unrelated quantities then the *in-block* position
|
|
478
477
|
* is not the note-level field either, so a check about the note-level field
|
|
479
478
|
* reads past it. `engine/frontmatter-lint.mjs` resolves that through
|
|
480
|
-
* `collidingBlockKeys`.
|
|
479
|
+
* `collidingBlockKeys`. Reading it for the emitted field alone is
|
|
481
480
|
* how an affiliation's office style came to answer for its page heading.
|
|
482
481
|
*/
|
|
483
482
|
topLevelMeans?: string | undefined;
|
|
@@ -511,13 +510,12 @@ export type FieldSpec = {
|
|
|
511
510
|
* third step of {@link module :engine/system-block.resolveFieldValue}'s order,
|
|
512
511
|
* so the value resolves whichever region carries it. What it tells the
|
|
513
512
|
* author-facing surfaces is which of the two is the field's *home*, so a
|
|
514
|
-
* message about it names `img` rather than sending an author to `sohl.img
|
|
515
|
-
* (#142).
|
|
513
|
+
* message about it names `img` rather than sending an author to `sohl.img`.
|
|
516
514
|
*/
|
|
517
515
|
shared?: boolean | undefined;
|
|
518
516
|
/**
|
|
519
517
|
* - The value's
|
|
520
|
-
* shape, for the frontmatter linter
|
|
518
|
+
* shape, for the frontmatter linter. Distinct from `shape`, which is
|
|
521
519
|
* prose for a reader, and from `read`, which is what the compiler does: a
|
|
522
520
|
* field may declare `kind` without changing a byte of what it emits, and
|
|
523
521
|
* several do — `weight` is coerced leniently but is still a number, and
|
|
@@ -539,7 +537,7 @@ export type FieldSpec = {
|
|
|
539
537
|
value?: any | ((fm: object) => any);
|
|
540
538
|
/**
|
|
541
539
|
* - **The key is left out entirely when
|
|
542
|
-
* the note does not carry the field
|
|
540
|
+
* the note does not carry the field**, rather than written from a
|
|
543
541
|
* declared default.
|
|
544
542
|
*
|
|
545
543
|
* Every other field answers absence with a value: an unauthored `weight` is
|
|
@@ -577,7 +575,7 @@ export type FieldSpec = {
|
|
|
577
575
|
/**
|
|
578
576
|
* - **What the field holds once play has
|
|
579
577
|
* started** — declared on a field the *document* writes for itself, which no
|
|
580
|
-
* note may author
|
|
578
|
+
* note may author.
|
|
581
579
|
*
|
|
582
580
|
* A schema declares plenty of fields a compiled document has no business
|
|
583
581
|
* carrying: an affliction's `onsetDate` is the world time its onset fired
|
|
@@ -27,7 +27,7 @@ export function folderAddress(pkg: string, shortcode: string): string;
|
|
|
27
27
|
* never run this build. Deriving it twice is how the index came to publish a
|
|
28
28
|
* plausible-looking id that resolved to nothing — the general id rule hashes a
|
|
29
29
|
* note's address under the `document` namespace, and a folder's is hashed under
|
|
30
|
-
* {@link FOLDER_ID_NAMESPACE}
|
|
30
|
+
* {@link FOLDER_ID_NAMESPACE}.
|
|
31
31
|
*
|
|
32
32
|
* An **authored `id` still wins**, and is applied by the caller: this is the
|
|
33
33
|
* derivation, not the resolution, so the pin rule stays stated once, where
|
|
@@ -42,8 +42,7 @@ export function folderDocId(pkg: string, shortcode: string): string;
|
|
|
42
42
|
* Collect every folder note in a content tree.
|
|
43
43
|
*
|
|
44
44
|
* The walk is the caller's to supply, so this stays testable without a tree on
|
|
45
|
-
* disk and so one build cannot disagree with another about what the corpus is
|
|
46
|
-
* (#243).
|
|
45
|
+
* disk and so one build cannot disagree with another about what the corpus is.
|
|
47
46
|
*
|
|
48
47
|
* @param {Iterable<{frontmatter: object|null, absPath: string}>} notes - As
|
|
49
48
|
* yielded by `walkMarkdownTree`.
|
|
@@ -62,7 +61,7 @@ export function collectFolderNotes(notes: Iterable<{
|
|
|
62
61
|
*
|
|
63
62
|
* Three keys per folder, and no more: the canonical address, the
|
|
64
63
|
* `folder-<shortcode>` short form, and the bare shortcode. They are the
|
|
65
|
-
* suffixes of the canonical address the grammar admits
|
|
64
|
+
* suffixes of the canonical address the grammar admits — a `packFolder`
|
|
66
65
|
* or `parent` field supplies the type itself, so a bare shortcode is a complete
|
|
67
66
|
* address there.
|
|
68
67
|
*
|
|
@@ -101,7 +100,7 @@ export function folderDocument(folder: FolderNote, parent: FolderNote | null, do
|
|
|
101
100
|
* Refuse a note that declares the retired `folder:` spelling.
|
|
102
101
|
*
|
|
103
102
|
* `folder:` named a compendium folder by the raw Foundry id declared in a
|
|
104
|
-
* per-pack `*-folders.yaml`. Both halves are retired together
|
|
103
|
+
* per-pack `*-folders.yaml`. Both halves are retired together: the id
|
|
105
104
|
* spelling has nothing left to resolve against once the YAML is gone, and the
|
|
106
105
|
* YAML has no reader once the spelling is refused.
|
|
107
106
|
*
|
|
@@ -112,7 +112,7 @@ export function fetchCatalogFromPath(config: object, rel: {
|
|
|
112
112
|
id: string;
|
|
113
113
|
}, source: string): Promise<string>;
|
|
114
114
|
/**
|
|
115
|
-
* Fetch one dependency's published content index
|
|
115
|
+
* Fetch one dependency's published content index.
|
|
116
116
|
*
|
|
117
117
|
* **The chain is entirely declared.** The relationship names the dependency's
|
|
118
118
|
* manifest, the manifest advertises `flags.metadataUrl`, and that URL is the
|
|
@@ -178,7 +178,7 @@ export function fetchAllCatalogs(config: object): Promise<number>;
|
|
|
178
178
|
* Reads the cache only. A cold cache is an error naming the command that fills
|
|
179
179
|
* it, rather than a download nobody asked for.
|
|
180
180
|
*
|
|
181
|
-
* **Scoped to one system when the caller compiles for one
|
|
181
|
+
* **Scoped to one system when the caller compiles for one**, exactly as
|
|
182
182
|
* {@link module:engine/generate.itemPackJsonDirs} scopes the local half. The
|
|
183
183
|
* two halves answer the same lookup — `loadItemsMap` merges them into one
|
|
184
184
|
* address space keyed by `subType:shortcode` — so scoping only the local one
|
|
@@ -200,7 +200,7 @@ export function foreignItemCatalogDirs(config: object, system?: string | null):
|
|
|
200
200
|
package: string;
|
|
201
201
|
}>;
|
|
202
202
|
/**
|
|
203
|
-
* The file a system publishes its `system` field sets as
|
|
203
|
+
* The file a system publishes its `system` field sets as.
|
|
204
204
|
*
|
|
205
205
|
* @type {string}
|
|
206
206
|
*/
|
|
@@ -20,8 +20,8 @@ export function anchorsOf(entryUuid: string, entryId: string, body: string, name
|
|
|
20
20
|
* An item note produces **two**: the item, and separately the JournalEntry its
|
|
21
21
|
* prose compiles into. They are two documents with two UUIDs, so they get two
|
|
22
22
|
* addresses; the item's entry points at the other by address rather than
|
|
23
|
-
* repeating its UUID, because the doc entry owns that fact
|
|
24
|
-
* note is the same arrangement
|
|
23
|
+
* repeating its UUID, because the doc entry owns that fact. A `macro`
|
|
24
|
+
* note is the same arrangement, which is why the type set comes from
|
|
25
25
|
* {@link hasDocEntry} rather than being spelled here — the journals compiler
|
|
26
26
|
* reads the same one, so a manifest cannot claim documentation nothing compiled.
|
|
27
27
|
*
|
|
@@ -33,7 +33,7 @@ export function anchorsOf(entryUuid: string, entryId: string, body: string, name
|
|
|
33
33
|
* UUID. The two are one fact — a UUID ends in the id — but only the entry knows
|
|
34
34
|
* which derivation produced it: an item's is its note's `fm.id`, and its
|
|
35
35
|
* documentation journal's is {@link itemDocEntryId} of that. Stating it here is
|
|
36
|
-
* what lets the content index publish an identity it did not re-derive
|
|
36
|
+
* what lets the content index publish an identity it did not re-derive.
|
|
37
37
|
*
|
|
38
38
|
* @param {object} ctx - Resolved identities: `{ contentPackage,
|
|
39
39
|
* foundryPackageId, packRouter }`.
|
|
@@ -44,12 +44,11 @@ export function entriesForNote(fm: object, name: string, address: string, body:
|
|
|
44
44
|
* Every note this package publishes, as manifest entries.
|
|
45
45
|
*
|
|
46
46
|
* Every note in the tree is this package's, so nothing here selects by package:
|
|
47
|
-
* the key's first segment is `contentPackage
|
|
47
|
+
* the key's first segment is `contentPackage`. A note still declaring the
|
|
48
48
|
* retired `package:` or `draft:` field **throws** rather than being skipped —
|
|
49
49
|
* skipping one silently is how a whole tree came to be filtered out of a
|
|
50
50
|
* manifest that then claimed the package published nothing, and it is what let
|
|
51
|
-
* a drafted note's inbound links look like links to a note that never existed
|
|
52
|
-
* (#69).
|
|
51
|
+
* a drafted note's inbound links look like links to a note that never existed.
|
|
53
52
|
*
|
|
54
53
|
* A note that has no address is **reported, not guessed** — the finding carries
|
|
55
54
|
* the file and the reason, so a caller can print it or fail on it. Inventing an
|
|
@@ -93,7 +92,7 @@ export function foundryIdentities(config?: object): {
|
|
|
93
92
|
* {@link foundryIdentities} plus what only a *manifest* emission needs. The
|
|
94
93
|
* split is what lets the content index derive the same Foundry addresses from
|
|
95
94
|
* the same code without also depending on whether the package publishes pages,
|
|
96
|
-
* which is no part of a UUID
|
|
95
|
+
* which is no part of a UUID.
|
|
97
96
|
*
|
|
98
97
|
* @param {object} [config] - A resolved configuration; loaded when omitted.
|
|
99
98
|
* @returns {{contentPackage: string, foundryPackageId: string, packRouter: object,
|
|
@@ -11,13 +11,13 @@
|
|
|
11
11
|
* than reported wholesale.
|
|
12
12
|
*/
|
|
13
13
|
/**
|
|
14
|
-
* Every system a configuration says its tree carries
|
|
14
|
+
* Every system a configuration says its tree carries.
|
|
15
15
|
*
|
|
16
16
|
* **Which systems a package ships for is already declared**, in three places
|
|
17
17
|
* that answer different questions, so this reads all three rather than asking a
|
|
18
18
|
* new one:
|
|
19
19
|
*
|
|
20
|
-
* - `systems:`
|
|
20
|
+
* - `systems:` declares them without requiring one, which is how a
|
|
21
21
|
* package ships for several;
|
|
22
22
|
* - a **pack's** `system:` is the same statement made per pack, and it is the
|
|
23
23
|
* one some trees make: `harn-ensemble` declares an `actors-sohl` and an
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
export function declaredSystems(config?: object): string[];
|
|
41
41
|
/**
|
|
42
42
|
* The system blocks a configuration says its tree carries, and what each
|
|
43
|
-
* accepts
|
|
43
|
+
* accepts.
|
|
44
44
|
*
|
|
45
45
|
* The lint checks the blocks its caller names, and for as long as there was one
|
|
46
46
|
* system the only caller named none — so every tree took the `sohl:` of
|
|
@@ -115,7 +115,7 @@ export function matchesKind(value: unknown, kind: string): boolean;
|
|
|
115
115
|
* @param {object} [opts.index] - The link index, for the reference check. Its
|
|
116
116
|
* absence skips that check rather than reporting every reference as dead.
|
|
117
117
|
* @param {Record<string, object>} [opts.vocabulary] - Type → the closed regions
|
|
118
|
-
* it declares, as `engine/note-vocabulary.mjs` states them
|
|
118
|
+
* it declares, as `engine/note-vocabulary.mjs` states them. Supplied
|
|
119
119
|
* by the caller for the same reason `schemas` is: this module validates a
|
|
120
120
|
* note against whatever its type declares and knows no type names of its
|
|
121
121
|
* own. Its absence skips the `data:` and `subType` checks rather than
|
|
@@ -125,7 +125,7 @@ export function matchesKind(value: unknown, kind: string): boolean;
|
|
|
125
125
|
* declaration, asked through `engine/generate.mjs`'s `emittedArtFor`.
|
|
126
126
|
* Supplied by the caller like `schemas`, so this module states no list of
|
|
127
127
|
* iconless types of its own; absent it, an inert `img:` goes unreported
|
|
128
|
-
* rather than every note's being
|
|
128
|
+
* rather than every note's being.
|
|
129
129
|
* @param {Readonly<Record<string, SystemBlockSpec>>} [opts.systems]
|
|
130
130
|
* The system blocks to check, and what each accepts. Supplied by the caller
|
|
131
131
|
* for the same reason `schemas` is — a build derives them from its
|
|
@@ -155,7 +155,7 @@ export function lintNote(note: object, { schemas, index, vocabulary, packs, emit
|
|
|
155
155
|
* @param {object} opts
|
|
156
156
|
* @param {Record<string, readonly object[]>} opts.schemas - Type → declaration.
|
|
157
157
|
* @param {Record<string, object>} [opts.vocabulary] - Type → the closed regions
|
|
158
|
-
* it declares
|
|
158
|
+
* it declares; see {@link lintNote}.
|
|
159
159
|
* @param {boolean} [opts.references=true] - Whether to check references.
|
|
160
160
|
* @param {Readonly<Record<string, SystemBlockSpec>>} [opts.systems]
|
|
161
161
|
* The system blocks to check; see {@link lintNote} and
|
|
@@ -191,7 +191,7 @@ export function lintFrontmatter(index: object, { schemas, vocabulary, packs, emi
|
|
|
191
191
|
*
|
|
192
192
|
* - `folder` — the compendium folder the document is filed in.
|
|
193
193
|
* - `pack` — which compendium of the note's document type receives it, for a
|
|
194
|
-
* repository shipping several
|
|
194
|
+
* repository shipping several.
|
|
195
195
|
* - `archetype` — the archetype flag, read for any note by the walk itself.
|
|
196
196
|
* - `kbcat` — the knowledgebase category a note is grouped under.
|
|
197
197
|
*
|
|
@@ -10,7 +10,7 @@ export function getFrontmatter(fm: any, key: any, defaultValue?: undefined): any
|
|
|
10
10
|
*/
|
|
11
11
|
export function sohlField(fm: any, key: any, defaultValue?: undefined): any;
|
|
12
12
|
/**
|
|
13
|
-
* Read a `sohl:` field, seeing the **destination** position as well
|
|
13
|
+
* Read a `sohl:` field, seeing the **destination** position as well.
|
|
14
14
|
*
|
|
15
15
|
* Five declarations resolve their value by re-reading the note rather than by
|
|
16
16
|
* taking the one {@link module:engine/system-block.resolveFieldValue} handed
|
|
@@ -29,8 +29,8 @@ export function sohlField(fm: any, key: any, defaultValue?: undefined): any;
|
|
|
29
29
|
*
|
|
30
30
|
* `legacyKey` is for the one pair whose two positions are spelled differently:
|
|
31
31
|
* a projectile authors `impact.die` and stores `impactBase.die`, so the reader
|
|
32
|
-
* has to be told both. It is the same split `FieldSpec.name`/`legacyKey` makes
|
|
33
|
-
*
|
|
32
|
+
* has to be told both. It is the same split `FieldSpec.name`/`legacyKey` makes,
|
|
33
|
+
* for the same reason — one name cannot key two positions.
|
|
34
34
|
*
|
|
35
35
|
* @param {object} fm - The note's frontmatter.
|
|
36
36
|
* @param {string} to - The key at the destination, dotted for a nested one.
|
|
@@ -46,7 +46,7 @@ export function sohlSystemField(fm: object, to: string, defaultValue?: any, { le
|
|
|
46
46
|
/**
|
|
47
47
|
* Resolve the `charges` block shared by Mystery and Mystical Ability items.
|
|
48
48
|
*
|
|
49
|
-
* Charge usage is carried by the **maximum** alone
|
|
49
|
+
* Charge usage is carried by the **maximum** alone: a `null` max means
|
|
50
50
|
* the item does not use charges at all, `0` means it is counted but uncapped,
|
|
51
51
|
* and a positive number is a real cap. `value` is the current count, with
|
|
52
52
|
* `null` meaning "infinite remaining". Both persist as nullable NumberFields,
|
|
@@ -87,7 +87,7 @@ export function resolveCharges(fm: object): {
|
|
|
87
87
|
export function resolveSkillAptitudes(fm: object, ctx?: string): Record<string, number>;
|
|
88
88
|
/**
|
|
89
89
|
* Resolve an affiliation's `relation` map — the shortcode of another
|
|
90
|
-
* affiliation → this one's standing toward it
|
|
90
|
+
* affiliation → this one's standing toward it.
|
|
91
91
|
*
|
|
92
92
|
* An unrecognized standing would fail the schema's `choices` validation at load
|
|
93
93
|
* and be dropped silently, shipping an affiliation whose authored hostility had
|
|
@@ -138,12 +138,12 @@ export function parseValueDesc(raw: any): {
|
|
|
138
138
|
* (`folder-poisonsandtoxins`), resolved through the address index the whole
|
|
139
139
|
* build shares. The `folder:` Foundry-id spelling this function once read
|
|
140
140
|
* beside it, and the per-pack `*-folders.yaml` that id was resolved against,
|
|
141
|
-
* are retired together
|
|
141
|
+
* are retired together — a note declaring `folder:` is refused by
|
|
142
142
|
* {@link module:engine/folder-notes.assertNoDeclaredFolder} rather than
|
|
143
143
|
* reaching here, so there is no second source for a value to come from.
|
|
144
144
|
*
|
|
145
145
|
* **`packFolder` was a path for one release** (`Possessions/Misc_Gear/Cooking`)
|
|
146
|
-
* and is an address now
|
|
146
|
+
* and is an address now. A path encoded the hierarchy *in the value*, so
|
|
147
147
|
* reparenting a folder made every note naming it wrong — a structural edit
|
|
148
148
|
* became a corpus-wide rewrite. An address is stable under reparenting, which
|
|
149
149
|
* is exactly why a note is addressed by `(type, shortcode)` and never by
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
export function compilerFor(docType: string, system?: string | null): Function | undefined;
|
|
11
11
|
/**
|
|
12
12
|
* The art fields a note of one content type reaches its document through, and
|
|
13
|
-
* the document it reaches
|
|
13
|
+
* the document it reaches.
|
|
14
14
|
*
|
|
15
15
|
* **Derived, never listed.** A note's type routes to a document type
|
|
16
16
|
* ({@link packForType}), a document type routes to the pass that compiles it
|
|
@@ -39,7 +39,7 @@ export function emittedArtFor(type: string): {
|
|
|
39
39
|
* The generated JSON of **every** configured Item pack — what the actors pass
|
|
40
40
|
* reads its predefined items from.
|
|
41
41
|
*
|
|
42
|
-
* All of them, not the first: a repository may ship several Item packs
|
|
42
|
+
* All of them, not the first: a repository may ship several Item packs,
|
|
43
43
|
* and an actor's embedded items may be sourced from any of them. Finding one
|
|
44
44
|
* pack and stopping is how embedded-item resolution would silently miss every
|
|
45
45
|
* item that landed in another. Returned in configured order, which is also the
|
|
@@ -47,7 +47,7 @@ export function emittedArtFor(type: string): {
|
|
|
47
47
|
* order among packs of one type — and every one of them is written before the
|
|
48
48
|
* actors pass that reads them.
|
|
49
49
|
*
|
|
50
|
-
* **Scoped to one system when the caller has one
|
|
50
|
+
* **Scoped to one system when the caller has one.** A being addresses an
|
|
51
51
|
* item by `(type, shortcode)`, and that address is unique within one system and
|
|
52
52
|
* not across two: `skill:sword` is an HM3 skill *and* a SoHL skill, with
|
|
53
53
|
* different data models behind them. The reference itself is unambiguous — it
|
|
@@ -65,7 +65,7 @@ export function emittedArtFor(type: string): {
|
|
|
65
65
|
* @returns {string[]} Each Item pack's JSON directory. Empty when the
|
|
66
66
|
* repository ships no items at all, which is a legitimate package: the actors
|
|
67
67
|
* pass accepts an empty list and reports an item it cannot resolve per
|
|
68
|
-
* `(type, shortcode)` instead, naming the being
|
|
68
|
+
* `(type, shortcode)` instead, naming the being.
|
|
69
69
|
*/
|
|
70
70
|
export function itemPackJsonDirs(config?: object, system?: string | null): string[];
|
|
71
71
|
/**
|
|
@@ -74,7 +74,7 @@ export function itemPackJsonDirs(config?: object, system?: string | null): strin
|
|
|
74
74
|
* An `Adventure` carries **copies**, not references, so a bundle resolves its
|
|
75
75
|
* `contents` against compiled output rather than against the content tree — the
|
|
76
76
|
* same arrangement the actors pass has for `itemsSourceDirs`, generalised to
|
|
77
|
-
* every document class an Adventure can hold
|
|
77
|
+
* every document class an Adventure can hold.
|
|
78
78
|
*
|
|
79
79
|
* Two kinds of pack are left out, each because it holds nothing a note
|
|
80
80
|
* addresses. A **prebuilt** pack's JSON is checked in rather than compiled, so
|
|
@@ -99,7 +99,7 @@ export function bundleSourceJsonDirs(config?: object, system?: string | null): R
|
|
|
99
99
|
/**
|
|
100
100
|
* The passes to run, ordered so that each one follows the output it reads.
|
|
101
101
|
*
|
|
102
|
-
* **Declaration order is presentation, not compile order
|
|
102
|
+
* **Declaration order is presentation, not compile order.** The same
|
|
103
103
|
* `packs:` list is the manifest's `packs` array, which a consumer orders for a
|
|
104
104
|
* reader browsing compendiums; the actors pass, meanwhile, resolves each
|
|
105
105
|
* being's embedded items against the item passes' *output*. Making one list
|
|
@@ -149,7 +149,7 @@ export function unsatisfiedPassDependencies(running: readonly object[], config:
|
|
|
149
149
|
*
|
|
150
150
|
* A pack ships blank whenever every note in a full tree was rejected — by a
|
|
151
151
|
* `selects` that claims nothing, or a `pack:` that routes everything elsewhere
|
|
152
|
-
* — and the build then exits 0
|
|
152
|
+
* — and the build then exits 0. The empty-tree guard in
|
|
153
153
|
* {@link generatePacksJson} cannot see that: the tree is full, it is the
|
|
154
154
|
* *output* that is empty.
|
|
155
155
|
*
|