@heroiclands/package-build 22.9.2 → 22.11.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 +56 -0
- package/CONTENT.md +54 -0
- package/bin/content-build.mjs +3 -1
- package/docs/api.md +11 -6
- package/docs/commands.md +1 -1
- package/docs/content-format.md +411 -201
- package/engine/actor-compiler.mjs +20 -7
- package/engine/address-fields.mjs +426 -0
- package/engine/address-values.mjs +80 -0
- package/engine/address.mjs +769 -0
- package/engine/art-fields.mjs +112 -97
- package/engine/art-slots.mjs +81 -0
- package/engine/base-compiler.mjs +61 -7
- package/engine/bundle-notes.mjs +5 -2
- package/engine/bundles.mjs +17 -10
- package/engine/content-address.mjs +23 -186
- package/engine/content-embeds.mjs +18 -4
- package/engine/content-format-check.mjs +50 -22
- package/engine/content-index.mjs +85 -43
- package/engine/content-links.mjs +105 -104
- package/engine/content-lint.mjs +11 -1
- package/engine/content-tables.mjs +9 -1
- package/engine/field-spec.mjs +21 -4
- package/engine/folder-notes.mjs +44 -15
- package/engine/foundry-entries.mjs +3 -0
- package/engine/frontmatter-lint.mjs +150 -47
- package/engine/frontmatter.mjs +55 -10
- package/engine/generate.mjs +7 -1
- package/engine/helpers.mjs +37 -9
- package/engine/holdings.mjs +41 -12
- package/engine/index-records.mjs +2 -0
- package/engine/infobox-render.mjs +2 -1
- package/engine/infobox.mjs +26 -6
- package/engine/item-compiler.mjs +5 -0
- package/engine/item-docs.mjs +7 -44
- package/engine/map-dot.mjs +2 -0
- package/engine/map-notes.mjs +7 -2
- package/engine/map-places.mjs +42 -10
- package/engine/metadata-index.mjs +60 -5
- package/engine/note-addresses.mjs +325 -0
- package/engine/note-vocabulary.mjs +140 -28
- package/engine/pdf-build.mjs +1 -1
- package/engine/pdf-toc.mjs +17 -2
- package/engine/place-relations.mjs +160 -50
- package/engine/populations.mjs +17 -9
- package/engine/reference-targets.mjs +54 -0
- package/engine/scenes.mjs +5 -2
- package/engine/shortcode-references.mjs +68 -0
- package/engine/site-build.mjs +39 -15
- package/engine/site-index.mjs +57 -75
- package/engine/sql-tables.mjs +43 -9
- package/engine/system-block.mjs +21 -0
- package/engine/system-vocabulary.mjs +46 -0
- package/engine/web-wikilinks.mjs +11 -9
- package/engine/wikilink-syntax.mjs +21 -0
- package/engine/wikilinks.mjs +92 -306
- package/hm3/actors.mjs +8 -24
- package/hm3/item-fields.mjs +15 -5
- package/package.json +1 -1
- package/sohl/infobox.mjs +111 -17
- package/sohl/item-fields.mjs +131 -41
- package/types/engine/address-fields.d.mts +95 -0
- package/types/engine/address-values.d.mts +34 -0
- package/types/engine/address.d.mts +452 -0
- package/types/engine/art-fields.d.mts +59 -53
- package/types/engine/art-slots.d.mts +40 -0
- package/types/engine/base-compiler.d.mts +24 -2
- package/types/engine/bundle-notes.d.mts +2 -2
- package/types/engine/content-address.d.mts +3 -139
- package/types/engine/content-embeds.d.mts +1 -1
- package/types/engine/content-format-check.d.mts +25 -0
- package/types/engine/content-index.d.mts +2 -2
- package/types/engine/content-links.d.mts +6 -5
- package/types/engine/field-spec.d.mts +46 -9
- package/types/engine/folder-notes.d.mts +11 -10
- package/types/engine/frontmatter-lint.d.mts +7 -97
- package/types/engine/frontmatter.d.mts +16 -1
- package/types/engine/helpers.d.mts +2 -2
- package/types/engine/infobox.d.mts +6 -0
- package/types/engine/item-docs.d.mts +1 -35
- package/types/engine/map-notes.d.mts +2 -2
- package/types/engine/note-addresses.d.mts +41 -0
- package/types/engine/note-vocabulary.d.mts +20 -3
- package/types/engine/place-relations.d.mts +12 -1
- package/types/engine/populations.d.mts +17 -2
- package/types/engine/reference-targets.d.mts +9 -0
- package/types/engine/shortcode-references.d.mts +14 -0
- package/types/engine/site-build.d.mts +3 -3
- package/types/engine/site-index.d.mts +9 -30
- package/types/engine/sql-tables.d.mts +2 -2
- package/types/engine/system-block.d.mts +17 -0
- package/types/engine/system-vocabulary.d.mts +16 -0
- package/types/engine/wikilink-syntax.d.mts +7 -0
- package/types/engine/wikilinks.d.mts +6 -109
- package/types/hm3/item-fields.d.mts +5 -0
- package/types/sohl/infobox.d.mts +6 -5
- package/types/sohl/item-fields.d.mts +8 -0
|
@@ -1,108 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Reads a qualifier as the **virtual `doc<type>`** form, or reports that it is
|
|
3
|
-
* not one.
|
|
4
|
-
*
|
|
5
|
-
* A document and its documentation are two documents in two packs, so they
|
|
6
|
-
* need two addresses. `skill/wpnc` is the item; `docskill/wpnc` is the
|
|
7
|
-
* JournalEntry its prose compiled into, and `docmacro/autoattack` is the same
|
|
8
|
-
* arrangement for a macro.
|
|
9
|
-
*
|
|
10
|
-
* The virtual form exists for a type that carries separate documentation
|
|
11
|
-
* ({@link sohl.utils.packs.docEntryTypes} — the set the journals compiler and
|
|
12
|
-
* the link manifest read too), **or** for one that routes to the items pack.
|
|
13
|
-
* The second clause is the older rule and stays: types that compile into items
|
|
14
|
-
* are the open, unenumerated set, and a foreign package may publish an
|
|
15
|
-
* item type this build has never heard of. Dropping it would silently unlink
|
|
16
|
-
* every `doc<type>` address into such a package.
|
|
17
|
-
*
|
|
18
|
-
* A **real** type of the same name always wins: the virtual reading is only
|
|
19
|
-
* consulted for a qualifier no authored note claims.
|
|
20
|
-
*
|
|
21
|
-
* @param {string} qualifier - The already-normalised text before the `/`.
|
|
22
|
-
* @param {Set<string>} types - Every type the content tree contains.
|
|
23
|
-
* @returns {string|null} The underlying document type, or `null` when the
|
|
24
|
-
* qualifier is not a virtual one.
|
|
25
|
-
*/
|
|
26
|
-
export function resolveItemDocType(qualifier: string, types: Set<string>): string | null;
|
|
27
|
-
/**
|
|
28
|
-
* Read a link target as a **qualified** `type-shortcode` reference, or report
|
|
29
|
-
* that it does not parse as one.
|
|
30
|
-
*
|
|
31
|
-
* Two separators are accepted, and they are **not** interchangeable in how
|
|
32
|
-
* confidently they mark a target as qualified:
|
|
33
|
-
*
|
|
34
|
-
* - **`type-shortcode`** and its qualified forms — the canonical spelling.
|
|
35
|
-
* Obsidian reads `/` inside a wikilink as a *path* and resolves it
|
|
36
|
-
* against the vault's folders, so a slash-qualified link is a broken link in
|
|
37
|
-
* the editor where the content is now authored.
|
|
38
|
-
* - **`type/shortcode`** — the legacy form, still resolved so that a link
|
|
39
|
-
* written before the vault migrated does not silently die. A slash is
|
|
40
|
-
* *unconditionally* a qualifier: nothing else uses one, so an unknown type
|
|
41
|
-
* before it is reported rather than guessed at. The split is at the **last**
|
|
42
|
-
* slash, as it always was.
|
|
43
|
-
*
|
|
44
|
-
* **The grammar is strict, and omission runs left to right**:
|
|
45
|
-
*
|
|
46
|
-
* ```text
|
|
47
|
-
* [[[[<package>-]<system>-]<type>-]<shortcode>]
|
|
48
|
-
* ```
|
|
49
|
-
*
|
|
50
|
-
* So the written forms are exactly the suffixes of the canonical address —
|
|
51
|
-
* `type-shortcode`, `system-type-shortcode`, `package-system-type-shortcode` —
|
|
52
|
-
* and **`package-type-shortcode` is not one of them**. A link into another
|
|
53
|
-
* package must therefore be fully qualified, which is the price of the segment
|
|
54
|
-
* being positional rather than tagged.
|
|
55
|
-
*
|
|
56
|
-
* **Parsing is plain positional counting**, the same rule
|
|
57
|
-
* {@link readCanonicalKey} follows, and it is sound for the same reason: every
|
|
58
|
-
* segment matches `ADDRESS_SEGMENT_PATTERN` (enforced on shortcodes by
|
|
59
|
-
* `content-lint.mjs`), so the hyphen is purely a
|
|
60
|
-
* separator and the count alone determines every field. Verified across the
|
|
61
|
-
* four content trees: 138,204 authored shortcodes, none carrying a separator.
|
|
62
|
-
*
|
|
63
|
-
* That replaced a first-hyphen split which let a shortcode contain a hyphen
|
|
64
|
-
* (`trauma-self-pro` → `trauma` + `self-pro`). The tolerance predates the
|
|
65
|
-
* charset rule and
|
|
66
|
-
* outlived it; no tree has used it, and keeping it would make a three-segment
|
|
67
|
-
* target ambiguous between a system and a hyphenated shortcode.
|
|
68
|
-
*
|
|
69
|
-
* **`sohl` is both a package and a system**, and positional counting is what
|
|
70
|
-
* makes that harmless: three segments is `<system>-<type>-<shortcode>` whatever
|
|
71
|
-
* the first segment could also have named, and four is the full form. Nothing
|
|
72
|
-
* has to guess which sense was meant.
|
|
73
|
-
*
|
|
74
|
-
* **A partial address states what it states, and the rest is not invented.** An
|
|
75
|
-
* omitted **system** is a *wildcard* — most links target items, which belong to
|
|
76
|
-
* a system — so the caller matches on the segments supplied and requires
|
|
77
|
-
* exactly one hit. An omitted **package** is instead *defaulted* to the citing
|
|
78
|
-
* note's own, so an unqualified link resolves locally and only locally.
|
|
79
|
-
*
|
|
80
|
-
* @param {string} target - The link target, anchor already removed.
|
|
81
|
-
* @param {Set<string>} types - Every type the content tree contains.
|
|
82
|
-
* @param {Set<string>} [packages] - Every package an address may name. Omitted
|
|
83
|
-
* by callers that resolve within one package, where the form cannot occur.
|
|
84
|
-
* @param {Set<string>} [noIndexPackages] - Packages declared `contentIndex:
|
|
85
|
-
* false` — a Foundry dependency only, with no fetched index. A fully
|
|
86
|
-
* qualified target naming one is refused with `no-content-index` before its
|
|
87
|
-
* type is even considered, since there is no index to resolve it against.
|
|
88
|
-
* @returns {{type: string, shortcode: string, itemDoc: boolean,
|
|
89
|
-
* package?: string, system?: string, reason?: undefined}
|
|
90
|
-
* | {reason: "unknown-type"|"no-content-index", package?: string} | null}
|
|
91
|
-
* The resolved qualifier; a `reason` when the target is definitely qualified
|
|
92
|
-
* but names no known type or no fetched index; or `null` when it is not an
|
|
93
|
-
* address at all.
|
|
94
|
-
*/
|
|
95
|
-
export function readQualifier(target: string, types: Set<string>, packages?: Set<string>, noIndexPackages?: Set<string>): {
|
|
96
|
-
type: string;
|
|
97
|
-
shortcode: string;
|
|
98
|
-
itemDoc: boolean;
|
|
99
|
-
package?: string;
|
|
100
|
-
system?: string;
|
|
101
|
-
reason?: undefined;
|
|
102
|
-
} | {
|
|
103
|
-
reason: "unknown-type" | "no-content-index";
|
|
104
|
-
package?: string;
|
|
105
|
-
} | null;
|
|
106
1
|
/**
|
|
107
2
|
* The deterministic JournalEntryPage id for one anchor: SHA-256 of
|
|
108
3
|
* `"<noteId>-<anchorSlug>"`, base64-encoded, reduced to the 16 alphanumeric
|
|
@@ -157,7 +52,7 @@ export function buildWikilinkIndex(docs: Array<{
|
|
|
157
52
|
docPack?: string;
|
|
158
53
|
none?: boolean;
|
|
159
54
|
draft?: boolean;
|
|
160
|
-
}>, packageId: string, foreign?: Map<string, object>, contentPackage?: string, { assets, noIndexPackages }?: {
|
|
55
|
+
}>, packageId: string, foreign?: Map<string, object>, contentPackage?: string, { assets, noIndexPackages, referenceTargets, foreignReferences }?: {
|
|
161
56
|
assets?: Map<string, object> | undefined;
|
|
162
57
|
noIndexPackages?: Set<string> | undefined;
|
|
163
58
|
}): {
|
|
@@ -232,16 +127,18 @@ export function convertWikilinks(markdown: string, { type, id, pack, docPack, in
|
|
|
232
127
|
* @param {object} index - From {@link buildWikilinkIndex}.
|
|
233
128
|
* @param {unknown} ref - The reference, as authored.
|
|
234
129
|
* @param {object} [hint] - `{type}`, where the caller knows what it expects.
|
|
235
|
-
* @returns {{name?: string, uuid?: string, address?:
|
|
130
|
+
* @returns {{name?: string, uuid?: string, address?: import("./address.mjs").AddressTuple, subType?: string}|undefined}
|
|
236
131
|
* The target, or `undefined` where nothing answers.
|
|
237
132
|
*/
|
|
238
133
|
export function resolveReference(index: object, ref: unknown, hint?: object): {
|
|
239
134
|
name?: string;
|
|
240
135
|
uuid?: string;
|
|
241
|
-
address?:
|
|
136
|
+
address?: import("./address.mjs").AddressTuple;
|
|
242
137
|
subType?: string;
|
|
243
138
|
} | undefined;
|
|
244
139
|
import { ITEM_PACK } from "./ids.mjs";
|
|
245
140
|
import { PACK_BY_TYPE } from "./ids.mjs";
|
|
246
141
|
import { packForType } from "./ids.mjs";
|
|
247
|
-
|
|
142
|
+
import { readQualifier } from "./address.mjs";
|
|
143
|
+
import { resolveItemDocType } from "./address.mjs";
|
|
144
|
+
export { ITEM_PACK, PACK_BY_TYPE, packForType, readQualifier, resolveItemDocType };
|
|
@@ -7,6 +7,11 @@
|
|
|
7
7
|
* a registry is addressed by what a note calls itself. What the document is
|
|
8
8
|
* called is the map's answer, and only the map's.
|
|
9
9
|
*
|
|
10
|
+
* Each field names both of its authored positions, as
|
|
11
|
+
* {@link module:hm3/actors} does and for the same reason: `name` is the shared
|
|
12
|
+
* source the content format's mapping tables state, and `legacyKey` is the key
|
|
13
|
+
* the `hm3:` block still carries.
|
|
14
|
+
*
|
|
10
15
|
* @type {Readonly<Record<string, readonly import("../engine/field-spec.mjs").FieldSpec[]>>}
|
|
11
16
|
*/
|
|
12
17
|
export const HM3_ITEM_FIELDS: Readonly<Record<string, readonly import("../engine/field-spec.mjs").FieldSpec[]>>;
|
package/types/sohl/infobox.d.mts
CHANGED
|
@@ -2,11 +2,10 @@
|
|
|
2
2
|
* What one entry of `sohl.items` names.
|
|
3
3
|
*
|
|
4
4
|
* An entry addresses its item three ways and every tree uses all three: a
|
|
5
|
-
* `model` address
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* which form a note happened to use.
|
|
5
|
+
* `model` address, explicit `type` / `shortcode` keys, or a locally authored
|
|
6
|
+
* item stating its type with the shortcode inside its own `system` block. One
|
|
7
|
+
* decode covers all of them, so nothing downstream has to know which form a
|
|
8
|
+
* note happened to use.
|
|
10
9
|
*
|
|
11
10
|
* @param {object} entry - One `sohl.items` entry.
|
|
12
11
|
* @returns {{type: string, shortcode: string, name: string, system: object}|undefined}
|
|
@@ -83,6 +82,8 @@ export function projectileSections(fm: object, ctx: object): object[];
|
|
|
83
82
|
* @returns {[string, object][]} Mode name → the mode.
|
|
84
83
|
*/
|
|
85
84
|
export function strikeModes(declared: unknown): [string, object][];
|
|
85
|
+
/** An affiliation presents skill documentation while retaining native Item identity. */
|
|
86
|
+
export function affiliationSections(fm: any, ctx: any): object[];
|
|
86
87
|
/** What this system's box is called. @type {string} */
|
|
87
88
|
export const SOHL_INFOBOX_TITLE: string;
|
|
88
89
|
/**
|
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
* Every item type's frontmatter vocabulary, in the order the `system` block
|
|
3
3
|
* emits it.
|
|
4
4
|
*
|
|
5
|
+
* **A field whose shared source is a path into `data:` names both positions.**
|
|
6
|
+
* `name` is the source the content format's mapping tables state — `data.seat`,
|
|
7
|
+
* `data.weight` — and `legacyKey` is the key the system block still carries, which
|
|
8
|
+
* wins while a tree writes it. Naming only the source would move the in-block
|
|
9
|
+
* read to a key spelled `data.seat`, which nothing authors; naming only the key
|
|
10
|
+
* leaves the container the specification points at unread, and the field then
|
|
11
|
+
* compiles its default over an authored value with nothing said.
|
|
12
|
+
*
|
|
5
13
|
* @type {Readonly<Record<string, readonly import("../engine/field-spec.mjs").FieldSpec[]>>}
|
|
6
14
|
*/
|
|
7
15
|
export const ITEM_FIELDS: Readonly<Record<string, readonly import("../engine/field-spec.mjs").FieldSpec[]>>;
|