@heroiclands/package-build 17.2.0 → 18.0.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 +1711 -0
- package/CONTENT.md +288 -72
- package/README.md +1 -1
- package/bin/content-build.mjs +218 -137
- package/bin/package-build.mjs +43 -0
- package/content-config.mjs +62 -67
- package/docs/content-format.md +768 -58
- package/engine/actor-compiler.mjs +586 -0
- package/engine/address-charset.mjs +11 -8
- package/engine/address-diff.mjs +266 -22
- package/engine/anchored-sections.mjs +83 -0
- package/engine/anchors.mjs +83 -0
- package/engine/base-compiler.mjs +148 -18
- package/engine/bundle-notes.mjs +276 -0
- package/engine/bundles.mjs +307 -0
- package/engine/code-fences.mjs +103 -0
- package/engine/compile-corpus.mjs +89 -0
- package/engine/content-address.mjs +267 -5
- package/engine/content-format-check.mjs +54 -11
- package/engine/content-format.mjs +37 -5
- package/engine/content-index.mjs +225 -127
- package/engine/content-links.mjs +185 -77
- package/engine/content-lint.mjs +232 -14
- package/engine/content-package.mjs +2 -1
- package/engine/content-tables.mjs +99 -3
- package/engine/document-subtypes.mjs +49 -6
- package/engine/field-reference.mjs +1 -1
- package/engine/field-spec.mjs +56 -6
- package/engine/folder-notes.mjs +470 -0
- package/engine/foreign-catalog.mjs +195 -4
- package/engine/{manifest-emit.mjs → foundry-entries.mjs} +55 -83
- package/engine/frontmatter-lint.mjs +245 -19
- package/engine/frontmatter.mjs +88 -8
- package/engine/generate.mjs +304 -13
- package/engine/helpers.mjs +293 -64
- package/engine/ids.mjs +137 -2
- package/engine/index-records.mjs +126 -0
- package/engine/index.mjs +23 -5
- package/engine/item-compiler.mjs +349 -0
- package/engine/item-docs.mjs +7 -1
- package/engine/item-registry.mjs +6 -0
- package/engine/journals.mjs +93 -27
- package/engine/macros.mjs +4 -2
- package/engine/metadata-index.mjs +495 -0
- package/engine/note-claims.mjs +146 -25
- package/engine/note-ids.mjs +112 -0
- package/engine/note-renames.mjs +134 -0
- package/engine/note-schemas.mjs +25 -0
- package/engine/note-vocabulary.mjs +110 -27
- package/engine/pack-config.mjs +4 -0
- package/engine/pack-router.mjs +23 -0
- package/engine/retired-fields.mjs +137 -3
- package/engine/scenes.mjs +66 -34
- package/engine/schema-check.mjs +58 -17
- package/engine/site-build.mjs +71 -12
- package/engine/site-index.mjs +20 -7
- package/engine/sql-tables.mjs +485 -0
- package/engine/subtype-registry.mjs +102 -0
- package/engine/system-block.mjs +96 -12
- package/engine/systems.mjs +201 -0
- package/engine/web-wikilinks.mjs +50 -20
- package/engine/wikilink-syntax.mjs +17 -8
- package/engine/wikilinks.mjs +124 -51
- package/engine/yaml-lint.mjs +282 -0
- package/hm3/actors.mjs +352 -0
- package/hm3/default-item-art.mjs +75 -0
- package/hm3/document-subtypes.mjs +134 -0
- package/hm3/index.mjs +56 -0
- package/hm3/item-builders.mjs +84 -0
- package/hm3/item-fields.mjs +180 -0
- package/hm3/items.mjs +96 -0
- package/hm3/template-priority.mjs +85 -0
- package/manifest.mjs +43 -2
- package/package.json +18 -4
- package/release.mjs +62 -7
- package/sohl/actors.mjs +33 -487
- package/sohl/being-info.mjs +16 -7
- package/sohl/default-item-art.mjs +14 -3
- package/sohl/document-subtypes.mjs +16 -10
- package/sohl/item-builders.mjs +14 -5
- package/sohl/item-fields.mjs +68 -7
- package/sohl/items.mjs +44 -258
- package/sohl/note-schemas.mjs +2 -2
- package/types/content-config.d.mts +21 -42
- package/types/engine/actor-compiler.d.mts +204 -0
- package/types/engine/address-charset.d.mts +11 -8
- package/types/engine/address-diff.d.mts +53 -5
- package/types/engine/anchored-sections.d.mts +21 -0
- package/types/engine/anchors.d.mts +20 -0
- package/types/engine/base-compiler.d.mts +17 -17
- package/types/engine/bundle-notes.d.mts +173 -0
- package/types/engine/bundles.d.mts +60 -0
- package/types/engine/code-fences.d.mts +43 -0
- package/types/engine/compile-corpus.d.mts +32 -0
- package/types/engine/content-address.d.mts +205 -5
- package/types/engine/content-format-check.d.mts +6 -2
- package/types/engine/content-format.d.mts +57 -1
- package/types/engine/content-index.d.mts +54 -49
- package/types/engine/content-links.d.mts +52 -7
- package/types/engine/content-lint.d.mts +10 -1
- package/types/engine/content-package.d.mts +2 -1
- package/types/engine/content-tables.d.mts +21 -39
- package/types/engine/document-subtypes.d.mts +37 -3
- package/types/engine/field-spec.d.mts +76 -5
- package/types/engine/folder-notes.d.mts +159 -0
- package/types/engine/foreign-catalog.d.mts +53 -0
- package/types/engine/{manifest-emit.d.mts → foundry-entries.d.mts} +2 -43
- package/types/engine/frontmatter-lint.d.mts +10 -2
- package/types/engine/frontmatter.d.mts +64 -0
- package/types/engine/generate.d.mts +38 -0
- package/types/engine/helpers.d.mts +94 -30
- package/types/engine/ids.d.mts +96 -0
- package/types/engine/index-records.d.mts +68 -0
- package/types/engine/index.d.mts +9 -3
- package/types/engine/item-compiler.d.mts +131 -0
- package/types/engine/journals.d.mts +47 -9
- package/types/engine/metadata-index.d.mts +226 -0
- package/types/engine/note-claims.d.mts +57 -11
- package/types/engine/note-ids.d.mts +38 -0
- package/types/engine/note-renames.d.mts +102 -0
- package/types/engine/note-vocabulary.d.mts +44 -8
- package/types/engine/retired-fields.d.mts +75 -0
- package/types/engine/scenes.d.mts +3 -2
- package/types/engine/schema-check.d.mts +25 -4
- package/types/engine/site-build.d.mts +4 -4
- package/types/engine/site-index.d.mts +1 -1
- package/types/engine/sql-tables.d.mts +185 -0
- package/types/engine/subtype-registry.d.mts +49 -0
- package/types/engine/system-block.d.mts +40 -1
- package/types/engine/systems.d.mts +106 -0
- package/types/engine/web-wikilinks.d.mts +4 -2
- package/types/engine/wikilink-syntax.d.mts +10 -3
- package/types/engine/wikilinks.d.mts +41 -13
- package/types/engine/yaml-lint.d.mts +107 -0
- package/types/hm3/actors.d.mts +48 -0
- package/types/hm3/default-item-art.d.mts +42 -0
- package/types/hm3/document-subtypes.d.mts +24 -0
- package/types/hm3/index.d.mts +7 -0
- package/types/hm3/item-builders.d.mts +11 -0
- package/types/hm3/item-fields.d.mts +12 -0
- package/types/hm3/items.d.mts +23 -0
- package/types/hm3/template-priority.d.mts +21 -0
- package/types/manifest.d.mts +22 -1
- package/types/release.d.mts +9 -4
- package/types/sohl/actors.d.mts +7 -74
- package/types/sohl/being-info.d.mts +8 -27
- package/types/sohl/default-item-art.d.mts +5 -3
- package/types/sohl/items.d.mts +17 -32
- package/engine/foreign-manifests.mjs +0 -126
- package/engine/kb-manifest.mjs +0 -490
- package/types/engine/foreign-manifests.d.mts +0 -43
- package/types/engine/kb-manifest.d.mts +0 -241
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Whether this package publishes the pages its content tree compiles to.
|
|
3
3
|
*
|
|
4
4
|
* The one question every reader of the mode actually asks — the site build, to
|
|
5
|
-
* decide whether to walk the tree at all, and the
|
|
5
|
+
* decide whether to walk the tree at all, and the content index, to
|
|
6
6
|
* decide whether an entry carries a web `path`. Written once here so the two
|
|
7
7
|
* cannot come to disagree about what a mode means.
|
|
8
8
|
*
|
|
@@ -39,13 +39,12 @@ export function defineConfig(config: ContentBuildConfigInput): ContentBuildConfi
|
|
|
39
39
|
export const PACKAGE_KINDS: readonly ["systems", "modules"];
|
|
40
40
|
export namespace DEFAULT_PATHS {
|
|
41
41
|
let content: "assets/content";
|
|
42
|
-
let manifests: "assets/manifests";
|
|
43
|
-
let manifestOut: "build/manifests";
|
|
44
42
|
let contentIndex: "build/content-index";
|
|
45
43
|
let packJson: "build/packs-json";
|
|
46
44
|
let stage: "build/stage/packs";
|
|
47
45
|
let unpack: "build/tmp/packs";
|
|
48
46
|
let foreignCache: "build/cache/foreign";
|
|
47
|
+
let metadataCache: "build/cache/metadata";
|
|
49
48
|
}
|
|
50
49
|
/**
|
|
51
50
|
* The Foundry document types a compendium pack may hold. This is the set the
|
|
@@ -89,7 +88,7 @@ export const RETIRED_ADDRESS_KEYS: Readonly<Record<string, string>>;
|
|
|
89
88
|
* `sohl`, whose knowledgebase is one surface among several, and empty for
|
|
90
89
|
* `thalorna`, whose site is nothing but its content. It is not the package's
|
|
91
90
|
* own mount point: where the package itself is served is the consuming build's
|
|
92
|
-
* knowledge, held in `PACKAGE_BASE` (`engine/
|
|
91
|
+
* knowledge, held in `PACKAGE_BASE` (`engine/content-address.mjs`) and prefixed at
|
|
93
92
|
* resolve time, so it is never recorded here (#1465).
|
|
94
93
|
*
|
|
95
94
|
* It is the whole scheme: `landing`, the key that named which note addressed a
|
|
@@ -110,7 +109,7 @@ export const DEFAULT_ADDRESS_SCHEME: Readonly<{
|
|
|
110
109
|
*
|
|
111
110
|
* - `homepage` — the authored homepage, and **no other page**. The content tree
|
|
112
111
|
* is not walked for pages, `site.sections` / `site.trees` / `site.landing`
|
|
113
|
-
* emit nothing, and
|
|
112
|
+
* emit nothing, and nothing serves a page for its addresses.
|
|
114
113
|
* - `content` — the homepage *plus* every page the content tree publishes: the
|
|
115
114
|
* knowledgebase, the extra trees, the section landings.
|
|
116
115
|
*
|
|
@@ -163,7 +162,7 @@ export const DERIVED_SYSTEM_VERSION: symbol;
|
|
|
163
162
|
*
|
|
164
163
|
* - `homepage` — the authored homepage, and **no other page**. The content tree
|
|
165
164
|
* is not walked for pages, `site.sections` / `site.trees` / `site.landing`
|
|
166
|
-
* emit nothing, and
|
|
165
|
+
* emit nothing, and nothing serves a page for its addresses.
|
|
167
166
|
* - `content` — the homepage *plus* every page the content tree publishes: the
|
|
168
167
|
* knowledgebase, the extra trees, the section landings.
|
|
169
168
|
*
|
|
@@ -284,19 +283,6 @@ export type PathsInput = {
|
|
|
284
283
|
* Content tree root.
|
|
285
284
|
*/
|
|
286
285
|
content?: string | undefined;
|
|
287
|
-
/**
|
|
288
|
-
* Vendored cross-package link manifests,
|
|
289
|
-
* read by `links`. Inbound.
|
|
290
|
-
*/
|
|
291
|
-
manifests?: string | undefined;
|
|
292
|
-
/**
|
|
293
|
-
* Where `manifest` writes this package's
|
|
294
|
-
* own link manifest. Outbound, and a
|
|
295
|
-
* build artifact — the published copy is
|
|
296
|
-
* the one a consumer vendors into its
|
|
297
|
-
* `manifests` directory.
|
|
298
|
-
*/
|
|
299
|
-
manifestOut?: string | undefined;
|
|
300
286
|
/**
|
|
301
287
|
* Where `content-index` writes this
|
|
302
288
|
* package's note index. Outbound, and a
|
|
@@ -316,18 +302,32 @@ export type PathsInput = {
|
|
|
316
302
|
* Where `unpack` extracts JSON back to.
|
|
317
303
|
*/
|
|
318
304
|
unpack?: string | undefined;
|
|
305
|
+
/**
|
|
306
|
+
* Where a dependency declaring
|
|
307
|
+
* `itemCatalog: true` is unpacked.
|
|
308
|
+
* Inbound, and fetched rather than
|
|
309
|
+
* committed.
|
|
310
|
+
*/
|
|
311
|
+
foreignCache?: string | undefined;
|
|
312
|
+
/**
|
|
313
|
+
* Where a dependency's published content
|
|
314
|
+
* index is fetched to (#239). Inbound,
|
|
315
|
+
* for *every* declared dependency, not
|
|
316
|
+
* only those supplying a catalogue.
|
|
317
|
+
*/
|
|
318
|
+
metadataCache?: string | undefined;
|
|
319
319
|
};
|
|
320
320
|
/**
|
|
321
321
|
* {@link PathsInput}, resolved to absolute paths against `rootDir`.
|
|
322
322
|
*/
|
|
323
323
|
export type ResolvedPaths = {
|
|
324
324
|
content: string;
|
|
325
|
-
manifests: string;
|
|
326
|
-
manifestOut: string;
|
|
327
325
|
contentIndex: string;
|
|
328
326
|
packJson: string;
|
|
329
327
|
stage: string;
|
|
330
328
|
unpack: string;
|
|
329
|
+
foreignCache: string;
|
|
330
|
+
metadataCache: string;
|
|
331
331
|
};
|
|
332
332
|
/**
|
|
333
333
|
* The identity every compiled document's `_stats` block carries.
|
|
@@ -371,32 +371,12 @@ export type StatsSpec = {
|
|
|
371
371
|
* two places for one fact.
|
|
372
372
|
*/
|
|
373
373
|
export type PackageBuildSection = Record<string, unknown>;
|
|
374
|
-
/**
|
|
375
|
-
* The two manifest switches. A package may publish a link manifest, consume
|
|
376
|
-
* other packages' manifests, both, or neither — the four combinations are all
|
|
377
|
-
* real (see #1385/#1446: `kethira` consumes but never publishes).
|
|
378
|
-
*/
|
|
379
|
-
export type ManifestSwitches = {
|
|
380
|
-
/**
|
|
381
|
-
* Emit this package's link manifest.
|
|
382
|
-
*/
|
|
383
|
-
publish: boolean;
|
|
384
|
-
/**
|
|
385
|
-
* Resolve cross-package links through vendored manifests.
|
|
386
|
-
*/
|
|
387
|
-
consume: boolean;
|
|
388
|
-
};
|
|
389
374
|
export type PublishSwitches = {
|
|
390
375
|
/**
|
|
391
376
|
* How much of this package reaches the web.
|
|
392
377
|
* See {@link SITE_MODES}.
|
|
393
378
|
*/
|
|
394
379
|
site: SiteMode;
|
|
395
|
-
manifests: ManifestSwitches;
|
|
396
|
-
};
|
|
397
|
-
export type ManifestSwitchesInput = {
|
|
398
|
-
publish?: boolean | undefined;
|
|
399
|
-
consume?: boolean | undefined;
|
|
400
380
|
};
|
|
401
381
|
/**
|
|
402
382
|
* The **Foundry core** version range this package supports.
|
|
@@ -512,7 +492,6 @@ export type DocsSpec = {
|
|
|
512
492
|
};
|
|
513
493
|
export type PublishSwitchesInput = {
|
|
514
494
|
site?: SiteMode | undefined;
|
|
515
|
-
manifests?: ManifestSwitchesInput | undefined;
|
|
516
495
|
address?: AddressSchemeInput | undefined;
|
|
517
496
|
};
|
|
518
497
|
export type AddressSchemeInput = {
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Strip compendium-only fields from a predefined item before embedding it
|
|
3
|
+
* inside an actor's `items[]`. These fields belong on a top-level
|
|
4
|
+
* compendium document, not on an embedded one.
|
|
5
|
+
*
|
|
6
|
+
* @param {object} item - The catalogue entry.
|
|
7
|
+
* @returns {object} The entry, without its compendium-only fields.
|
|
8
|
+
*/
|
|
9
|
+
export function stripCompendiumFields(item: object): object;
|
|
10
|
+
/**
|
|
11
|
+
* Whether a value is a plain object, for {@link deepMerge}.
|
|
12
|
+
*
|
|
13
|
+
* @param {unknown} v - The value.
|
|
14
|
+
* @returns {boolean} True for a plain object.
|
|
15
|
+
*/
|
|
16
|
+
export function isPlainObject(v: unknown): boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Recursively merge `overlay` onto `base`. Plain objects merge key-by-key;
|
|
19
|
+
* everything else (arrays, primitives, null) replaces. Inputs are not
|
|
20
|
+
* mutated.
|
|
21
|
+
*
|
|
22
|
+
* @param {any} base - The catalogue entry.
|
|
23
|
+
* @param {any} overlay - The note's own values.
|
|
24
|
+
* @returns {any} The merged value.
|
|
25
|
+
*/
|
|
26
|
+
export function deepMerge(base: any, overlay: any): any;
|
|
27
|
+
/**
|
|
28
|
+
* The key one predefined item is held under, and every place that spells it.
|
|
29
|
+
*
|
|
30
|
+
* **The vocabulary is the document's, not the note's** — `subType` is the
|
|
31
|
+
* Foundry Item subtype the compiled document carries, which is the only thing a
|
|
32
|
+
* compiled pack (or an extracted dependency catalogue) records about what an
|
|
33
|
+
* item *is*. An actor's frontmatter addresses the same item in the *note*
|
|
34
|
+
* vocabulary, so a reference is translated forward through the system's map
|
|
35
|
+
* before it reaches this function; see
|
|
36
|
+
* {@link SystemActorCompiler#embeddedSubtype} for why the translation goes that
|
|
37
|
+
* way and not the other (#140).
|
|
38
|
+
*
|
|
39
|
+
* @param {string} subType - The Foundry Item subtype.
|
|
40
|
+
* @param {string} shortcode - The item's `system.shortcode`.
|
|
41
|
+
* @returns {string} The address, `subType:shortcode`.
|
|
42
|
+
*/
|
|
43
|
+
export function itemAddress(subType: string, shortcode: string): string;
|
|
44
|
+
/**
|
|
45
|
+
* What identifies one embedded item on its actor.
|
|
46
|
+
*
|
|
47
|
+
* **Its own `system.shortcode`** — not the entry's top-level `shortcode`, which
|
|
48
|
+
* merely *selects* the catalogue template the entry is written from and is
|
|
49
|
+
* never written to the document. Two daggers may share a selector; they are two
|
|
50
|
+
* embodiments and each must declare its own.
|
|
51
|
+
*
|
|
52
|
+
* The name is a last resort, for a **stand-alone** entry that names no template
|
|
53
|
+
* and states no shortcode. It is a poor identity — presentation, and free to be
|
|
54
|
+
* localized or to diverge — so it is not a fallback the compiler is content
|
|
55
|
+
* with: two entries reducing to one identity is refused either way, and the
|
|
56
|
+
* message says to state a `system.shortcode`.
|
|
57
|
+
*
|
|
58
|
+
* @param {object} item - The merged embedded item.
|
|
59
|
+
* @returns {string} The identity, for {@link embeddedItemId}.
|
|
60
|
+
*/
|
|
61
|
+
export function embeddedIdentity(item: object): string;
|
|
62
|
+
/**
|
|
63
|
+
* The `_id` of one item embedded on an actor.
|
|
64
|
+
*
|
|
65
|
+
* Seeded by the owning actor, because an embedded id must be unique within its
|
|
66
|
+
* **parent document** and nothing wider — so the namespace is already exactly
|
|
67
|
+
* the scope the uniqueness is required in, and the largest namespace in the
|
|
68
|
+
* four corpora holds 180 items, at which 64 bits collide with probability
|
|
69
|
+
* around 10⁻¹⁵.
|
|
70
|
+
*
|
|
71
|
+
* **It takes no index** (#268). Keying on a position meant reordering a being's
|
|
72
|
+
* item list renumbered every id after the change, so a re-import created new
|
|
73
|
+
* documents beside the old ones — while nothing about those documents had
|
|
74
|
+
* changed, only their neighbours. The identity always exists or must be stated;
|
|
75
|
+
* see {@link embeddedIdentity}.
|
|
76
|
+
*
|
|
77
|
+
* Keyed by the **document subtype**, so renaming a note type (#78) leaves every
|
|
78
|
+
* embedded id where it was.
|
|
79
|
+
*
|
|
80
|
+
* @param {string} actorId - The owning actor's id.
|
|
81
|
+
* @param {string} subType - The Foundry Item subtype.
|
|
82
|
+
* @param {string} identity - From {@link embeddedIdentity}.
|
|
83
|
+
* @returns {string} A 16-character Foundry id.
|
|
84
|
+
*/
|
|
85
|
+
export function embeddedItemId(actorId: string, subType: string, identity: string): string;
|
|
86
|
+
/**
|
|
87
|
+
* Load every JSON file under each of `itemsSourceDirs`, returning one Map keyed
|
|
88
|
+
* by {@link itemAddress} — the compiled document's **subtype** and its
|
|
89
|
+
* `system.shortcode`. Folder docs and entries without a shortcode are skipped.
|
|
90
|
+
* The `_key` field is stripped from each entry — it is not part of the item
|
|
91
|
+
* data model.
|
|
92
|
+
*
|
|
93
|
+
* The directories are read as one address space, because an actor names an item
|
|
94
|
+
* by `(type, shortcode)` and never by the pack it happens to ship in. Two local
|
|
95
|
+
* Item packs claiming the same address is therefore ambiguous rather than a
|
|
96
|
+
* last-one-wins ordering detail, and fails here.
|
|
97
|
+
*
|
|
98
|
+
* A **foreign** directory — the extracted item catalogue of a package this
|
|
99
|
+
* repository depends on but does not contain — is a fallback rather than a
|
|
100
|
+
* peer. A repository must be able to ship its own `skill:awar` that stands in
|
|
101
|
+
* front of the system's, so a local address shadows a foreign one instead of
|
|
102
|
+
* colliding with it. Local directories are therefore read first, and anything
|
|
103
|
+
* already claimed is left alone.
|
|
104
|
+
*
|
|
105
|
+
* @param {readonly string[]} itemsSourceDirs - Every local Item pack's JSON tree.
|
|
106
|
+
* @param {readonly string[]} [foreignSourceDirs] - Extracted dependency
|
|
107
|
+
* catalogues, consulted only for addresses no local pack defines.
|
|
108
|
+
* @returns {Map<string, object>} The predefined items, by address.
|
|
109
|
+
*/
|
|
110
|
+
export function loadItemsMap(itemsSourceDirs: readonly string[], foreignSourceDirs?: readonly string[]): Map<string, object>;
|
|
111
|
+
/**
|
|
112
|
+
* The Actor compile pass of one game system.
|
|
113
|
+
*
|
|
114
|
+
* A subclass declares its {@link SystemActorCompiler.documentSubtypes} and
|
|
115
|
+
* implements `buildEntry`, which is where the system's own data model is: what
|
|
116
|
+
* an actor's `system` block holds, which art it defaults to, which frontmatter
|
|
117
|
+
* becomes embedded items. Nothing above that line is a system's business.
|
|
118
|
+
*/
|
|
119
|
+
export class SystemActorCompiler extends BasePackCompiler {
|
|
120
|
+
/**
|
|
121
|
+
* The note-type → document-subtype map this pass compiles against.
|
|
122
|
+
*
|
|
123
|
+
* Stated by the class rather than reached for through a module import, so
|
|
124
|
+
* every subtype decision the pass makes — the actor's own, and each
|
|
125
|
+
* embedded item reference's — reads one declaration that a subclass
|
|
126
|
+
* compiling for another system replaces.
|
|
127
|
+
*
|
|
128
|
+
* @type {import("./document-subtypes.mjs").DocumentSubtypeMap|undefined}
|
|
129
|
+
*/
|
|
130
|
+
static documentSubtypes: import("./document-subtypes.mjs").DocumentSubtypeMap | undefined;
|
|
131
|
+
constructor({ itemsSourceDirs, foreignSourceDirs, ...options }: {
|
|
132
|
+
[x: string]: any;
|
|
133
|
+
itemsSourceDirs?: never[] | undefined;
|
|
134
|
+
foreignSourceDirs?: never[] | undefined;
|
|
135
|
+
});
|
|
136
|
+
/** @type {readonly string[]} */
|
|
137
|
+
itemsSourceDirs: readonly string[];
|
|
138
|
+
foreignSourceDirs: any;
|
|
139
|
+
/**
|
|
140
|
+
* This pass's system map, or a message naming the class that forgot it.
|
|
141
|
+
*
|
|
142
|
+
* @returns {import("./document-subtypes.mjs").DocumentSubtypeMap} The map.
|
|
143
|
+
*/
|
|
144
|
+
get documentSubtypes(): import("./document-subtypes.mjs").DocumentSubtypeMap;
|
|
145
|
+
/**
|
|
146
|
+
* The frontmatter block this pass reads.
|
|
147
|
+
*
|
|
148
|
+
* @returns {string} The system's block name.
|
|
149
|
+
*/
|
|
150
|
+
get system(): string;
|
|
151
|
+
itemsMap: Map<string, object> | undefined;
|
|
152
|
+
/** @inheritdoc */
|
|
153
|
+
reportDetail(stats: any): void;
|
|
154
|
+
/**
|
|
155
|
+
* The Foundry Item subtype an embedded reference's `type` addresses.
|
|
156
|
+
*
|
|
157
|
+
* **The reference is in the note vocabulary; the address is in the
|
|
158
|
+
* document's** (#140). An actor writes `(type, shortcode)` with the type an
|
|
159
|
+
* author authors, while {@link itemAddress} keys the predefined items by
|
|
160
|
+
* the subtype each compiled document carries — so exactly one of the two
|
|
161
|
+
* sides has to translate, and it is this one. The system's map is a
|
|
162
|
+
* function from note type to subtype by construction; the reverse is not,
|
|
163
|
+
* and a compiled document records nothing about the note that produced it,
|
|
164
|
+
* so there is no honest way to key the addresses the other way round.
|
|
165
|
+
*
|
|
166
|
+
* @param {string} type - The type the reference names.
|
|
167
|
+
* @returns {import("./document-subtypes.mjs").ReferencedSubtype} The
|
|
168
|
+
* subtype, or why the reference names none.
|
|
169
|
+
*/
|
|
170
|
+
embeddedSubtype(type: string): import("./document-subtypes.mjs").ReferencedSubtype;
|
|
171
|
+
/**
|
|
172
|
+
* Resolve one embedded item from a `(type, shortcode?, overlay)`
|
|
173
|
+
* descriptor. If `shortcode` is given, the predefined item is fetched
|
|
174
|
+
* from `itemsMap` and the overlay deep-merged on top. If absent, the
|
|
175
|
+
* descriptor must carry enough fields to stand alone. The embedded
|
|
176
|
+
* item's `_id` is regenerated deterministically from
|
|
177
|
+
* `(actorId, subType, shortcode, indexKey)` so re-exports are stable —
|
|
178
|
+
* from the **document subtype**, so that renaming a note type (#78) leaves
|
|
179
|
+
* every embedded id exactly where it was.
|
|
180
|
+
* Returns null if the descriptor cannot be resolved.
|
|
181
|
+
*
|
|
182
|
+
* @param {Map<string, object>} itemsMap - The predefined items, by address.
|
|
183
|
+
* @param {string} actorId - The owning actor's id, seeding embedded ids.
|
|
184
|
+
* @param {string} type - The **note** type the reference names.
|
|
185
|
+
* @param {string|null} shortcode - The referenced item's shortcode, or
|
|
186
|
+
* `null` for a stand-alone entry.
|
|
187
|
+
* @param {object} [overlay] - The entry's remaining properties.
|
|
188
|
+
* @param {string} indexKey - Where the reference sits, for a diagnostic.
|
|
189
|
+
* It no longer reaches the id (#268) — it names the entry in a message.
|
|
190
|
+
* @param {string} ctx - Diagnostic context (the actor's label).
|
|
191
|
+
* @param {object} [at] - Where to locate a finding.
|
|
192
|
+
* @param {string} [at.fmKey] - The frontmatter key the reference sits
|
|
193
|
+
* under, so an unresolved one is reported at the reference rather than
|
|
194
|
+
* at the note.
|
|
195
|
+
* @returns {object|null} The embedded item, or null when it resolved to
|
|
196
|
+
* nothing — always with a finding emitted.
|
|
197
|
+
*/
|
|
198
|
+
resolveEmbedded(itemsMap: Map<string, object>, actorId: string, type: string, shortcode: string | null, overlay?: object, indexKey: string, ctx: string, { fmKey }?: {
|
|
199
|
+
fmKey?: string | undefined;
|
|
200
|
+
}): object | null;
|
|
201
|
+
#private;
|
|
202
|
+
}
|
|
203
|
+
import { BasePackCompiler } from "./base-compiler.mjs";
|
|
204
|
+
export { extractAnchorSection, renderSection } from "./anchored-sections.mjs";
|
|
@@ -13,19 +13,22 @@ export function isAddressSegment(value: unknown): boolean;
|
|
|
13
13
|
/**
|
|
14
14
|
* The one charset every segment of a canonical address is held to (#59).
|
|
15
15
|
*
|
|
16
|
-
* An address is a hyphen-joined tuple — `
|
|
17
|
-
* by **counting segments**, with a
|
|
18
|
-
* for exactly one reason: the hyphen
|
|
19
|
-
* segment may contain one. Take that away
|
|
20
|
-
* vocabulary to match against, a longest-match
|
|
21
|
-
* name that is a prefix of another — none of
|
|
16
|
+
* An address is a hyphen-joined tuple — `package-system-type-shortcode`, so
|
|
17
|
+
* `sohl-none-doc-gear` — and it is read back by **counting segments**, with a
|
|
18
|
+
* fixed meaning per position. That is sound for exactly one reason: the hyphen
|
|
19
|
+
* is *purely* a separator, because no segment may contain one. Take that away
|
|
20
|
+
* and reading an address needs a vocabulary to match against, a longest-match
|
|
21
|
+
* rule, and an answer for every name that is a prefix of another — none of
|
|
22
|
+
* which exist.
|
|
22
23
|
*
|
|
23
24
|
* So the charset is not a tidiness rule. It is the premise the address grammar
|
|
24
25
|
* rests on, and the issue's word for how it should be held is **enforced rather
|
|
25
26
|
* than assumed**: a value that breaks it is refused where it is written, not
|
|
26
27
|
* discovered later as addresses that fail to parse and report nothing about
|
|
27
|
-
* why. `harn-adventures` was that case —
|
|
28
|
-
*
|
|
28
|
+
* why. `harn-adventures` was that case — a package whose own name carries the
|
|
29
|
+
* separator emits keys one segment too long, so `harn-adventures-sohl-skill-melee`
|
|
30
|
+
* counts five where the grammar requires four, and every one of them failed as
|
|
31
|
+
* a `null` return.
|
|
29
32
|
*
|
|
30
33
|
* This module is a **leaf with no local imports**, so the validator a
|
|
31
34
|
* consumer's `package-build.config.mjs` reaches (`content-config.mjs`) can name
|
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The one spelling of an address in this space: `type:shortcode`.
|
|
3
|
+
*
|
|
4
|
+
* Written by both readers — the compiled packs on each side of the diff, and
|
|
5
|
+
* the declarations read out of the tree — so a predecessor a note names and an
|
|
6
|
+
* address a pack publishes cannot come apart over punctuation or case. The
|
|
7
|
+
* shortcode is used **verbatim**, not lowercased: `readItemAddresses` reads it
|
|
8
|
+
* off the compiled document, where `Tabri` is stored as authored, and folding
|
|
9
|
+
* case here would join two addresses the packs keep apart.
|
|
10
|
+
*
|
|
11
|
+
* @param {string} type - The Foundry document subtype, not the note type.
|
|
12
|
+
* @param {string} shortcode - The address's `system.shortcode`.
|
|
13
|
+
* @returns {string} The address key.
|
|
14
|
+
*/
|
|
15
|
+
export function itemAddressKey(type: string, shortcode: string): string;
|
|
1
16
|
/**
|
|
2
17
|
* The address space a set of compiled Item pack directories publishes.
|
|
3
18
|
*
|
|
@@ -24,6 +39,9 @@ export function readItemAddresses(dirs: readonly string[]): Map<string, {
|
|
|
24
39
|
shortcode: string;
|
|
25
40
|
file: string;
|
|
26
41
|
}>;
|
|
42
|
+
export function declaredPredecessors(contentBase: any, { skipDirectories, maps, config, records, problems }?: {
|
|
43
|
+
maps?: readonly import("./document-subtypes.mjs").DocumentSubtypeMap[] | undefined;
|
|
44
|
+
}): Map<any, any>;
|
|
27
45
|
/**
|
|
28
46
|
* Every address the baseline published that this build does not.
|
|
29
47
|
*
|
|
@@ -36,12 +54,20 @@ export function readItemAddresses(dirs: readonly string[]): Map<string, {
|
|
|
36
54
|
* @param {object} opts
|
|
37
55
|
* @param {string} opts.baseline - What the baseline is, for the message —
|
|
38
56
|
* conventionally `<package>@<version>`.
|
|
57
|
+
* @param {Map<string, {to: string, file: string}>} [opts.predecessors] - The
|
|
58
|
+
* declared renames, from {@link declaredPredecessors}. Omitted, the diff
|
|
59
|
+
* falls back to the id join alone and reports an unpinned rename as a
|
|
60
|
+
* withdrawal, which is what it did before #278.
|
|
39
61
|
* @returns {Array<object>} One finding per departed address, in address order
|
|
40
|
-
* so two runs read the same. `kind` is `"renamed"` (with `to`
|
|
41
|
-
* `"withdrawn"`.
|
|
62
|
+
* so two runs read the same. `kind` is `"renamed"` (with `to`, and `declared`
|
|
63
|
+
* when it was the note's word rather than an id match) or `"withdrawn"`.
|
|
42
64
|
*/
|
|
43
|
-
export function diffItemAddresses(baseline: Map<string, object>, current: Map<string, object>, { baseline: label }: {
|
|
65
|
+
export function diffItemAddresses(baseline: Map<string, object>, current: Map<string, object>, { baseline: label, predecessors }: {
|
|
44
66
|
baseline: string;
|
|
67
|
+
predecessors?: Map<string, {
|
|
68
|
+
to: string;
|
|
69
|
+
file: string;
|
|
70
|
+
}> | undefined;
|
|
45
71
|
}): Array<object>;
|
|
46
72
|
/**
|
|
47
73
|
* Every content note in a tree, indexed by the document id it authors.
|
|
@@ -53,11 +79,18 @@ export function diffItemAddresses(baseline: Map<string, object>, current: Map<st
|
|
|
53
79
|
*
|
|
54
80
|
* @param {string} contentBase - Root of the content tree.
|
|
55
81
|
* @param {object} [opts]
|
|
56
|
-
* @param {readonly string[]} [opts.skipDirectories] -
|
|
82
|
+
* @param {readonly string[]} [opts.skipDirectories] - The corpus scope, stated
|
|
83
|
+
* by the caller — see {@link addressCorpus}.
|
|
84
|
+
* @param {object} [opts.config] - The resolved build configuration, which the
|
|
85
|
+
* id is derived against. See {@link addressCorpus} for why that matters.
|
|
86
|
+
* @param {readonly object[]} [opts.records] - Index records the caller already
|
|
87
|
+
* derived, shared with {@link declaredPredecessors}.
|
|
57
88
|
* @returns {Map<string, string>} Document id → the note's absolute path.
|
|
58
89
|
*/
|
|
59
|
-
export function noteFilesById(contentBase: string, { skipDirectories }?: {
|
|
90
|
+
export function noteFilesById(contentBase: string, { skipDirectories, config, records, problems }?: {
|
|
60
91
|
skipDirectories?: readonly string[] | undefined;
|
|
92
|
+
config?: object | undefined;
|
|
93
|
+
records?: readonly object[] | undefined;
|
|
61
94
|
}): Map<string, string>;
|
|
62
95
|
/**
|
|
63
96
|
* Where to send the reader for one finding.
|
|
@@ -69,6 +102,11 @@ export function noteFilesById(contentBase: string, { skipDirectories }?: {
|
|
|
69
102
|
* address existing. When neither is readable the position is **dropped**, never
|
|
70
103
|
* defaulted to `1:1`.
|
|
71
104
|
*
|
|
105
|
+
* A **declared** rename knows its note without any lookup — the declaration is
|
|
106
|
+
* how it was found — and is reported at the `renamedFrom:` line rather than the
|
|
107
|
+
* `shortcode:` line, because that is the line the finding is about and the one
|
|
108
|
+
* the author deletes once the declaration has done its work (#278).
|
|
109
|
+
*
|
|
72
110
|
* @param {object} finding - One finding from {@link diffItemAddresses}.
|
|
73
111
|
* @param {Map<string, string>} noteFiles - From {@link noteFilesById}.
|
|
74
112
|
* @returns {{file?: string, line?: number, column?: number}} Spreadable
|
|
@@ -88,6 +126,16 @@ export function locateAddressFinding(finding: object, noteFiles: Map<string, str
|
|
|
88
126
|
* known — and says so, rather than leaving the reader to wonder whether one was
|
|
89
127
|
* looked for.
|
|
90
128
|
*
|
|
129
|
+
* **A declared rename says it is declared** (#278). The two claims are not
|
|
130
|
+
* equally checkable: an id match is a fact in the artefacts, while a
|
|
131
|
+
* declaration is an author's word, and a reader deciding whether to trust the
|
|
132
|
+
* successor needs to know which one they have. Saying "the same document" of a
|
|
133
|
+
* declared rename would spend the id match's credibility on it.
|
|
134
|
+
*
|
|
135
|
+
* The consequence sentence is the same for both, because it is the same
|
|
136
|
+
* consequence: the old address stops resolving either way, and that is what
|
|
137
|
+
* the reader has to act on.
|
|
138
|
+
*
|
|
91
139
|
* @param {object} finding - One finding from {@link diffItemAddresses}.
|
|
92
140
|
* @returns {string} The message.
|
|
93
141
|
*/
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extract the body of an H1 section whose heading carries the explicit
|
|
3
|
+
* anchor decorator `{#<anchorId>}`. Captures every line after the H1 up
|
|
4
|
+
* to (but not including) the next H1 — nested H2/H3 etc. and their bodies
|
|
5
|
+
* are included. The H1 line itself is discarded. Returns "" if no such
|
|
6
|
+
* heading exists. Fenced code blocks are respected so `# foo` inside
|
|
7
|
+
* ``` blocks does not trigger a match.
|
|
8
|
+
*
|
|
9
|
+
* @param {string} body - The note body.
|
|
10
|
+
* @param {string} anchorId - The anchor to find.
|
|
11
|
+
* @returns {string} The section's markdown, or "".
|
|
12
|
+
*/
|
|
13
|
+
export function extractAnchorSection(body: string, anchorId: string): string;
|
|
14
|
+
/**
|
|
15
|
+
* Render an extracted markdown section to HTML, or "" if empty.
|
|
16
|
+
*
|
|
17
|
+
* @param {string} body - The note body.
|
|
18
|
+
* @param {string} anchorId - The anchor to find.
|
|
19
|
+
* @returns {string} The rendered HTML, or "".
|
|
20
|
+
*/
|
|
21
|
+
export function renderSection(body: string, anchorId: string): string;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `{#slug}` anchors a note's body declares, with where each one sits.
|
|
3
|
+
*
|
|
4
|
+
* Only headings carrying an explicit anchor are collected. A bare `#` heading
|
|
5
|
+
* also starts a journal page, but it declares no slug, so nothing can address
|
|
6
|
+
* it with `#…` — listing it would offer a link that cannot be written.
|
|
7
|
+
*
|
|
8
|
+
* @param {string} body - The note's markdown body, frontmatter already removed.
|
|
9
|
+
* @param {number} [bodyLine] - The 1-based file line the body starts on, from
|
|
10
|
+
* `parseMarkdownFile`. Anchors are reported at their position in the **file**,
|
|
11
|
+
* so an editor can jump straight to one; passing nothing numbers from the body.
|
|
12
|
+
* @returns {Array<{slug: string, name: string, level: number, line: number}>}
|
|
13
|
+
* In document order.
|
|
14
|
+
*/
|
|
15
|
+
export function collectAnchors(body: string, bodyLine?: number): Array<{
|
|
16
|
+
slug: string;
|
|
17
|
+
name: string;
|
|
18
|
+
level: number;
|
|
19
|
+
line: number;
|
|
20
|
+
}>;
|
|
@@ -103,6 +103,8 @@ export class BasePackCompiler {
|
|
|
103
103
|
* @param {object} options
|
|
104
104
|
* @param {string} options.contentBase - Root of the content tree.
|
|
105
105
|
* @param {string} options.dest - Where this pass writes its JSON.
|
|
106
|
+
* @param {readonly string[]} options.skipDirectories - Directories the walk
|
|
107
|
+
* never descends into. Required: see {@link assertStatedScope}.
|
|
106
108
|
* @param {(path: string|null) => string|null} [options.folderResolver] -
|
|
107
109
|
* Resolves a `sohl.folder` id against this pack's folder hierarchy.
|
|
108
110
|
* @param {string} [options.packName] - The pack this pass writes.
|
|
@@ -112,9 +114,10 @@ export class BasePackCompiler {
|
|
|
112
114
|
* @param {boolean} [options.routingReporter] - Whether this pass reports a
|
|
113
115
|
* note of its type that routes nowhere.
|
|
114
116
|
*/
|
|
115
|
-
constructor({ contentBase, dest, folderResolver, packName, packSystem, docType, router, routingReporter, }?: {
|
|
117
|
+
constructor({ contentBase, dest, skipDirectories, folderResolver, packName, packSystem, docType, router, routingReporter, corpus, }?: {
|
|
116
118
|
contentBase: string;
|
|
117
119
|
dest: string;
|
|
120
|
+
skipDirectories: readonly string[];
|
|
118
121
|
folderResolver?: ((path: string | null) => string | null) | undefined;
|
|
119
122
|
packName?: string | undefined;
|
|
120
123
|
docType?: string | undefined;
|
|
@@ -189,6 +192,7 @@ export class BasePackCompiler {
|
|
|
189
192
|
*/
|
|
190
193
|
unresolvedLinks: number;
|
|
191
194
|
packSystem: any;
|
|
195
|
+
corpus: any;
|
|
192
196
|
/**
|
|
193
197
|
* The `_stats` block every entry this pass emits is stamped with (#48).
|
|
194
198
|
*
|
|
@@ -224,9 +228,12 @@ export class BasePackCompiler {
|
|
|
224
228
|
* instances of.
|
|
225
229
|
*
|
|
226
230
|
* @param {object} fm - The note's frontmatter.
|
|
227
|
-
* @returns {boolean} True when the note may be compiled here
|
|
228
|
-
*
|
|
229
|
-
*
|
|
231
|
+
* @returns {boolean} True when the note may be compiled here; `false` when
|
|
232
|
+
* it belongs to another system's pass of the same document type, which is
|
|
233
|
+
* skipped as quietly as any other note this pack does not own.
|
|
234
|
+
* @throws {Error} When this pack's system is absent from the note and no
|
|
235
|
+
* other configured system claims it. The error carries a `position` where
|
|
236
|
+
* the note's own file can be read.
|
|
230
237
|
*/
|
|
231
238
|
eligibleFor(fm: object): boolean;
|
|
232
239
|
/**
|
|
@@ -267,17 +274,10 @@ export class BasePackCompiler {
|
|
|
267
274
|
* @returns {Promise<void>}
|
|
268
275
|
*/
|
|
269
276
|
prepare(): Promise<void>;
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
contentDocs: {
|
|
275
|
-
fm: object;
|
|
276
|
-
path: string;
|
|
277
|
-
tld: string;
|
|
278
|
-
folder: string;
|
|
279
|
-
absPath: string;
|
|
280
|
-
}[] | undefined;
|
|
277
|
+
reportsCorpusProblems: boolean | undefined;
|
|
278
|
+
linkIndex: any;
|
|
279
|
+
contentDocs: any;
|
|
280
|
+
sqlTables: any;
|
|
281
281
|
/**
|
|
282
282
|
* The body {@link BasePackCompiler#buildEntry} receives.
|
|
283
283
|
*
|
|
@@ -344,7 +344,7 @@ export class BasePackCompiler {
|
|
|
344
344
|
* The sibling of {@link BasePackCompiler#reportUndeclaredSystemData}, and
|
|
345
345
|
* the half that sees what no declaration states. A compiler writes keys of
|
|
346
346
|
* its own alongside the declared fields — `shortcode`, `actionDefs`,
|
|
347
|
-
* `notes`, `docHtml`, `
|
|
347
|
+
* `notes`, `docHtml`, `templatePriority` — and neither the field-declaration check
|
|
348
348
|
* nor the authored-`system` check can see them, so until this nothing
|
|
349
349
|
* compared them at all. Foundry's discard is the same silent one either
|
|
350
350
|
* way.
|
|
@@ -369,7 +369,7 @@ export class BasePackCompiler {
|
|
|
369
369
|
* @param {object} [opts.config] - The resolved build configuration.
|
|
370
370
|
* @returns {number} How many findings were new to this pass.
|
|
371
371
|
*/
|
|
372
|
-
reportEmittedSystemData(
|
|
372
|
+
reportEmittedSystemData(emitted: any, { fm, block, documentType, subType, type, fields, config }: {
|
|
373
373
|
fm: object;
|
|
374
374
|
block: string;
|
|
375
375
|
documentType: string;
|