@heroiclands/package-build 24.0.2 → 24.0.3
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 +18 -0
- package/bin/content-commands.mjs +8 -10
- package/content-config.mjs +1 -52
- package/docs/api.md +14 -8
- package/docs/authoring/links-and-markup.md +1 -1
- package/docs/commands.md +4 -6
- package/docs/configuration.md +13 -69
- package/docs/guides/site.md +3 -1
- package/docs/reference/format-details.md +19 -71
- package/docs/reference/note-types.md +3 -2
- package/engine/content-charset.mjs +1 -0
- package/engine/dictionary-layout.mjs +16 -3
- package/engine/foreign-catalog.mjs +11 -122
- package/engine/language-rows.mjs +3 -3
- package/engine/language-terms.mjs +7 -1
- package/engine/pdf-build.mjs +9 -178
- package/engine/site-reach.mjs +23 -0
- package/engine/site-render.mjs +18 -3
- package/package.json +2 -1
- package/types/content-config.d.mts +1 -19
- package/types/engine/dictionary-layout.d.mts +5 -0
- package/types/engine/foreign-catalog.d.mts +0 -38
- package/types/engine/language-rows.d.mts +1 -1
- package/types/engine/pdf-build.d.mts +5 -27
- package/types/engine/site-reach.d.mts +11 -0
- package/engine/asset-replacement.mjs +0 -93
- package/types/engine/asset-replacement.d.mts +0 -22
|
@@ -313,8 +313,7 @@ export type PathsInput = {
|
|
|
313
313
|
unpack?: string | undefined;
|
|
314
314
|
/**
|
|
315
315
|
* Where a dependency declaring
|
|
316
|
-
* `itemCatalog: true`
|
|
317
|
-
* `assetArchive: true` is unpacked.
|
|
316
|
+
* `itemCatalog: true` is unpacked.
|
|
318
317
|
* Inbound, and fetched rather than
|
|
319
318
|
* committed.
|
|
320
319
|
*/
|
|
@@ -486,13 +485,6 @@ export type RelationshipSpec = {
|
|
|
486
485
|
* does not hold. Needs a `manifest`.
|
|
487
486
|
*/
|
|
488
487
|
itemCatalog?: boolean | undefined;
|
|
489
|
-
/**
|
|
490
|
-
* Whether `deps fetch` unpacks this
|
|
491
|
-
* dependency's release archive for its
|
|
492
|
-
* asset bytes alone, building no item
|
|
493
|
-
* catalogue from it. Needs a `manifest`.
|
|
494
|
-
*/
|
|
495
|
-
assetArchive?: boolean | undefined;
|
|
496
488
|
/**
|
|
497
489
|
* Whether `deps fetch` fetches this
|
|
498
490
|
* dependency's content index. Default
|
|
@@ -504,16 +496,6 @@ export type RelationshipSpec = {
|
|
|
504
496
|
* index.
|
|
505
497
|
*/
|
|
506
498
|
contentIndex?: boolean | undefined;
|
|
507
|
-
/**
|
|
508
|
-
* Whether this dependency's asset
|
|
509
|
-
* tree answers this package's own asset
|
|
510
|
-
* addresses ahead of its local record.
|
|
511
|
-
* Default `false`. Refuses `contentIndex:
|
|
512
|
-
* false` on the same entry, since a
|
|
513
|
-
* replacement with no fetched index to
|
|
514
|
-
* check against resolves nothing.
|
|
515
|
-
*/
|
|
516
|
-
assetReplacement?: boolean | undefined;
|
|
517
499
|
};
|
|
518
500
|
/**
|
|
519
501
|
* How a generated documentation page is framed in the repository publishing it.
|
|
@@ -60,6 +60,11 @@ export const LAYOUT_REQUIRED_COLUMNS: Readonly<{
|
|
|
60
60
|
export const COMMON_MARK: "\u2022";
|
|
61
61
|
/** The word-entry span class whose Foundry rendering is a native TOC heading. */
|
|
62
62
|
export const DICTIONARY_ENTRY_CLASS: "dictionary-entry";
|
|
63
|
+
/**
|
|
64
|
+
* The class on every link an entry writes to another note, so a site can set
|
|
65
|
+
* the link as plain text where its target is not a page a reader can reach.
|
|
66
|
+
*/
|
|
67
|
+
export const LEXICAL_LINK_CLASS: "lexical-ref";
|
|
63
68
|
export type LayoutOptions = {
|
|
64
69
|
/**
|
|
65
70
|
* - Whether an Address can be
|
|
@@ -11,20 +11,6 @@ export function itemCatalogRelationships(config: object): Array<{
|
|
|
11
11
|
kind: string;
|
|
12
12
|
verified: string | undefined;
|
|
13
13
|
}>;
|
|
14
|
-
/**
|
|
15
|
-
* Every declared relationship that opted into supplying its release archive
|
|
16
|
-
* for asset bytes alone, with no item catalogue built from it.
|
|
17
|
-
*
|
|
18
|
-
* @param {object} config - The resolved build configuration.
|
|
19
|
-
* @returns {Array<{id: string, manifest: string, kind: string, verified: string|undefined}>}
|
|
20
|
-
* The opted-in relationships, in declaration order.
|
|
21
|
-
*/
|
|
22
|
-
export function assetArchiveRelationships(config: object): Array<{
|
|
23
|
-
id: string;
|
|
24
|
-
manifest: string;
|
|
25
|
-
kind: string;
|
|
26
|
-
verified: string | undefined;
|
|
27
|
-
}>;
|
|
28
14
|
/**
|
|
29
15
|
* The cache directory for one dependency at one version.
|
|
30
16
|
*
|
|
@@ -109,26 +95,6 @@ export function fetchCatalog(config: object, rel: {
|
|
|
109
95
|
id: string;
|
|
110
96
|
manifest: string;
|
|
111
97
|
}): Promise<string>;
|
|
112
|
-
/**
|
|
113
|
-
* Fetch one dependency's release archive for its asset bytes alone, building
|
|
114
|
-
* no item catalogue from it.
|
|
115
|
-
*
|
|
116
|
-
* Idempotent: a complete cache for the resolved version is left alone. Where a
|
|
117
|
-
* relationship also declares `itemCatalog: true`, {@link fetchCatalog} already
|
|
118
|
-
* unpacked this same archive into this same cache directory, and
|
|
119
|
-
* {@link fetchAllCatalogs} does not call this function for it — the two never
|
|
120
|
-
* download the same bytes twice.
|
|
121
|
-
*
|
|
122
|
-
* @param {object} config - The resolved build configuration.
|
|
123
|
-
* @param {{id: string, manifest: string, verified?: string}} rel - The
|
|
124
|
-
* declared relationship.
|
|
125
|
-
* @returns {Promise<string>} The dependency's cache directory.
|
|
126
|
-
*/
|
|
127
|
-
export function fetchAssetArchive(config: object, rel: {
|
|
128
|
-
id: string;
|
|
129
|
-
manifest: string;
|
|
130
|
-
verified?: string;
|
|
131
|
-
}): Promise<string>;
|
|
132
98
|
/**
|
|
133
99
|
* Fill the cache from a locally built artifact rather than a release.
|
|
134
100
|
*
|
|
@@ -202,10 +168,6 @@ export function fetchAllMetadata(config: object): Promise<number>;
|
|
|
202
168
|
/**
|
|
203
169
|
* Fetch every opted-in dependency. The `deps fetch` command.
|
|
204
170
|
*
|
|
205
|
-
* A relationship declaring both `itemCatalog: true` and `assetArchive: true`
|
|
206
|
-
* is fetched once: {@link fetchCatalog} already unpacks the archive on its
|
|
207
|
-
* way to extracting the item catalogue, so this skips the archive-only fetch
|
|
208
|
-
* for any id {@link fetchCatalog} already handled.
|
|
209
171
|
*
|
|
210
172
|
* @param {object} config - The resolved build configuration.
|
|
211
173
|
* @returns {Promise<number>} How many dependencies were fetched.
|
|
@@ -215,7 +215,7 @@ export function joinRows(records: Iterable<Record<string, any>>): object[];
|
|
|
215
215
|
*/
|
|
216
216
|
export function markRows(records: Iterable<Record<string, any>>): object[];
|
|
217
217
|
/**
|
|
218
|
-
* The `skeleton` rows: one per `data.sounds.skeleton` entry, `second`
|
|
218
|
+
* The `skeleton` rows: one per `data.sounds.skeleton` entry, `second` and `third` lists.
|
|
219
219
|
*
|
|
220
220
|
* @param {Iterable<Record<string, any>>} records - Index records.
|
|
221
221
|
* @returns {object[]}
|
|
@@ -14,33 +14,16 @@
|
|
|
14
14
|
* a build from touching a path outside its own output.
|
|
15
15
|
*
|
|
16
16
|
* A file **this** package ships stages directly. A pathname naming another
|
|
17
|
-
* package's file
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* answers it; `opts.foreignIndex` is the merged index that answer is read
|
|
21
|
-
* against. A pathname naming a package no replacement carries it for, or a
|
|
22
|
-
* URL, names something no build here can open — a build reaches no network —
|
|
23
|
-
* and the caller reports it as a picture the book will not carry.
|
|
17
|
+
* package's file, or a URL, names something no build here can open — a build
|
|
18
|
+
* reaches no network — and the caller reports it as a picture the book will
|
|
19
|
+
* not carry.
|
|
24
20
|
*
|
|
25
21
|
* @param {string} src - The pathname, as authored.
|
|
26
22
|
* @param {object} config - The resolved configuration.
|
|
27
|
-
* @param {object} [opts]
|
|
28
|
-
* @param {Map<string, object>} [opts.foreignIndex] - Every fetched
|
|
29
|
-
* dependency's own records, keyed by canonical address — the index a
|
|
30
|
-
* replacement's record is read out of.
|
|
31
|
-
* @param {Function} [opts.resolveReplacement] - {@link
|
|
32
|
-
* module:engine/asset-replacement.resolveAssetReplacement}, or an
|
|
33
|
-
* equivalent a caller injects for a test. Omitted, a foreign pathname this
|
|
34
|
-
* package does not own stays declined exactly as it always has.
|
|
35
23
|
* @returns {{from: string, to: string}|null} The file, and where under the
|
|
36
24
|
* output directory it is staged.
|
|
37
|
-
* @throws {Error} When a declared replacement answers the address but its
|
|
38
|
-
* archive was never fetched.
|
|
39
25
|
*/
|
|
40
|
-
export function stagedImagePath(src: string, config: object
|
|
41
|
-
foreignIndex?: Map<string, object> | undefined;
|
|
42
|
-
resolveReplacement?: Function | undefined;
|
|
43
|
-
}): {
|
|
26
|
+
export function stagedImagePath(src: string, config: object): {
|
|
44
27
|
from: string;
|
|
45
28
|
to: string;
|
|
46
29
|
} | null;
|
|
@@ -134,10 +117,6 @@ export function listBookAssets({ config, version, out }?: {
|
|
|
134
117
|
* {@link module:engine/pdf-pages}.
|
|
135
118
|
* @param {Function} [opts.readPages] - {@link
|
|
136
119
|
* module:engine/pdf-pages.readEntryPages}, for tests.
|
|
137
|
-
* @param {Function} [opts.resolveReplacement] - {@link
|
|
138
|
-
* module:engine/asset-replacement.resolveAssetReplacement}, for tests.
|
|
139
|
-
* Loaded from that module otherwise, and only when a relationship declares
|
|
140
|
-
* `assetReplacement: true` — a build with none never imports it.
|
|
141
120
|
* @returns {Promise<{built: boolean, reason: string|null, findings: object[],
|
|
142
121
|
* imageReports: object[], books: Array<{id: string, title: string,
|
|
143
122
|
* built: boolean, typ: string, pdf: string|null, stats: object}>,
|
|
@@ -149,7 +128,7 @@ export function listBookAssets({ config, version, out }?: {
|
|
|
149
128
|
* every declared book whichever was requested; both are empty when a book's
|
|
150
129
|
* selection could not be read.
|
|
151
130
|
*/
|
|
152
|
-
export function buildPdf({ config, configPath, book, out, version, compile, readPages,
|
|
131
|
+
export function buildPdf({ config, configPath, book, out, version, compile, readPages, }?: {
|
|
153
132
|
config?: object | undefined;
|
|
154
133
|
configPath?: string | undefined;
|
|
155
134
|
book?: string | undefined;
|
|
@@ -157,7 +136,6 @@ export function buildPdf({ config, configPath, book, out, version, compile, read
|
|
|
157
136
|
version?: string | undefined;
|
|
158
137
|
compile?: boolean | undefined;
|
|
159
138
|
readPages?: Function | undefined;
|
|
160
|
-
resolveReplacement?: Function | undefined;
|
|
161
139
|
}): Promise<{
|
|
162
140
|
built: boolean;
|
|
163
141
|
reason: string | null;
|
|
@@ -67,6 +67,17 @@ export function splitContent(html: string): {
|
|
|
67
67
|
* @returns {string} The sections, or `""` when nothing is left.
|
|
68
68
|
*/
|
|
69
69
|
export function pruneGenerated(html: string, outside: (href: string) => boolean): string;
|
|
70
|
+
/**
|
|
71
|
+
* Entries' links set as plain text where they lead outside a set of pages.
|
|
72
|
+
* Each link is the only child of a span carrying the class.
|
|
73
|
+
*
|
|
74
|
+
* @param {string} html - A page body.
|
|
75
|
+
* @param {(href: string) => boolean} outside - Whether an `href` names a page
|
|
76
|
+
* of the site that is not to be linked.
|
|
77
|
+
* @param {string} className - The class the entries' links carry.
|
|
78
|
+
* @returns {string} The body with each such `<a>` replaced by its content.
|
|
79
|
+
*/
|
|
80
|
+
export function unlinkEntries(html: string, outside: (href: string) => boolean, className: string): string;
|
|
70
81
|
/**
|
|
71
82
|
* The comment that separates a page's authored text from the sections the
|
|
72
83
|
* build generated after it, in the HTML the renderer writes.
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* This file is part of the Song of Heroic Lands (SoHL) system for Foundry VTT.
|
|
3
|
-
* Copyright (c) 2024-2026 Tom Rodriguez ("Toasty") — <toasty@heroiclands.org>
|
|
4
|
-
*
|
|
5
|
-
* This work is licensed under the GNU General Public License v3.0 (GPLv3).
|
|
6
|
-
* You may copy, modify, and distribute it under the terms of that license.
|
|
7
|
-
*
|
|
8
|
-
* For full terms, see the LICENSE.md file in the project root or visit:
|
|
9
|
-
* https://www.gnu.org/licenses/gpl-3.0.html
|
|
10
|
-
*
|
|
11
|
-
* SPDX-License-Identifier: GPL-3.0-or-later
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* A declared replacement package's asset record, picked over the local one,
|
|
16
|
-
* by address.
|
|
17
|
-
*
|
|
18
|
-
* A package may declare, on a `relationships.<kind>[]` entry, that a
|
|
19
|
-
* dependency's asset tree answers its own asset addresses —
|
|
20
|
-
* `assetReplacement: true` in `package-build.config.yaml`:
|
|
21
|
-
*
|
|
22
|
-
* ```yaml
|
|
23
|
-
* relationships:
|
|
24
|
-
* requires:
|
|
25
|
-
* - id: thalornaaltart
|
|
26
|
-
* manifest: https://…/releases/latest/download/module.json
|
|
27
|
-
* assetReplacement: true
|
|
28
|
-
* contentIndex: true
|
|
29
|
-
* ```
|
|
30
|
-
*
|
|
31
|
-
* `assetReplacement: true` opts that relationship in. `resolveAssetReplacement`
|
|
32
|
-
* is what turns the declaration into an answer, one address at a time, against
|
|
33
|
-
* four rules:
|
|
34
|
-
*
|
|
35
|
-
* 1. **Scoped to asset types.** A non-asset address, or one whose package
|
|
36
|
-
* segment is not the compiling package's own, resolves to `null` at once —
|
|
37
|
-
* tested with {@link module:engine/asset-types.isAssetType} rather than
|
|
38
|
-
* reimplemented. A being, an item or a lore note is never replaced this
|
|
39
|
-
* way.
|
|
40
|
-
* 2. **Ordered, single pass.** Replacements are tried in declaration order —
|
|
41
|
-
* the order their relationships appear in `package-build.config.yaml` —
|
|
42
|
-
* and the first one carrying the address wins.
|
|
43
|
-
* 3. **Never recursive.** A replacement's own output address is not itself
|
|
44
|
-
* looked up against another replacement: resolving
|
|
45
|
-
* `thalornaaltart-none-image-thorn` never asks whether something replaces
|
|
46
|
-
* `thalornaaltart`. This forecloses a cycle by construction — there is
|
|
47
|
-
* nothing to loop.
|
|
48
|
-
* 4. **A miss falls through.** `null` means no declared replacement carries
|
|
49
|
-
* the address, and the caller falls back to the local address exactly as
|
|
50
|
-
* it does today. This function never decides that a missing replacement is
|
|
51
|
-
* an error; a caller that wants that is free to build it on the answer.
|
|
52
|
-
*
|
|
53
|
-
* This resolver answers a different question from
|
|
54
|
-
* {@link module:engine/asset-bindings.checkForeignAssetBindings}: that check
|
|
55
|
-
* validates an art module's own staged files against another package's
|
|
56
|
-
* addresses, at that module's own build time. This one runs at the *replaced*
|
|
57
|
-
* package's build, consulted by its book, and asks whether a declared
|
|
58
|
-
* replacement carries an address this package would otherwise answer itself.
|
|
59
|
-
*
|
|
60
|
-
* @module
|
|
61
|
-
*/
|
|
62
|
-
|
|
63
|
-
import { isAssetType } from "./asset-types.mjs";
|
|
64
|
-
import { canonicalKey, readCanonicalKey } from "./content-address.mjs";
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* The replacement record for one asset address, or `null`.
|
|
68
|
-
*
|
|
69
|
-
* @param {string} address - A canonical asset address.
|
|
70
|
-
* @param {object} opts
|
|
71
|
-
* @param {string} opts.localPackage - The compiling package's own segment.
|
|
72
|
-
* @param {readonly string[]} opts.replacements - The package segments of
|
|
73
|
-
* every relationship declaring `assetReplacement: true`, in declaration
|
|
74
|
-
* order.
|
|
75
|
-
* @param {Map<string, object>} opts.index - The merged content index, keyed
|
|
76
|
-
* by canonical address.
|
|
77
|
-
* @returns {{record: object, package: string}|null} The first replacement
|
|
78
|
-
* carrying the address, or `null` when none does.
|
|
79
|
-
*/
|
|
80
|
-
export function resolveAssetReplacement(address, { localPackage, replacements, index }) {
|
|
81
|
-
const parts = readCanonicalKey(address);
|
|
82
|
-
if (!parts) return null;
|
|
83
|
-
if (!isAssetType(parts.type)) return null;
|
|
84
|
-
if (parts.package !== localPackage) return null;
|
|
85
|
-
for (const replacementPackage of replacements ?? []) {
|
|
86
|
-
const key = canonicalKey(replacementPackage, parts.system, parts.type, parts.shortcode);
|
|
87
|
-
const record = index?.get(key);
|
|
88
|
-
if (record?.asset?.path && record.package) {
|
|
89
|
-
return { record, package: replacementPackage };
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
return null;
|
|
93
|
-
}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The replacement record for one asset address, or `null`.
|
|
3
|
-
*
|
|
4
|
-
* @param {string} address - A canonical asset address.
|
|
5
|
-
* @param {object} opts
|
|
6
|
-
* @param {string} opts.localPackage - The compiling package's own segment.
|
|
7
|
-
* @param {readonly string[]} opts.replacements - The package segments of
|
|
8
|
-
* every relationship declaring `assetReplacement: true`, in declaration
|
|
9
|
-
* order.
|
|
10
|
-
* @param {Map<string, object>} opts.index - The merged content index, keyed
|
|
11
|
-
* by canonical address.
|
|
12
|
-
* @returns {{record: object, package: string}|null} The first replacement
|
|
13
|
-
* carrying the address, or `null` when none does.
|
|
14
|
-
*/
|
|
15
|
-
export function resolveAssetReplacement(address: string, { localPackage, replacements, index }: {
|
|
16
|
-
localPackage: string;
|
|
17
|
-
replacements: readonly string[];
|
|
18
|
-
index: Map<string, object>;
|
|
19
|
-
}): {
|
|
20
|
-
record: object;
|
|
21
|
-
package: string;
|
|
22
|
-
} | null;
|