@heroiclands/package-build 17.1.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.
Files changed (153) hide show
  1. package/CHANGELOG.md +1773 -0
  2. package/CONTENT.md +288 -72
  3. package/README.md +1 -1
  4. package/bin/content-build.mjs +218 -137
  5. package/bin/package-build.mjs +43 -0
  6. package/content-config.mjs +62 -67
  7. package/docs/content-format.md +768 -58
  8. package/engine/actor-compiler.mjs +586 -0
  9. package/engine/address-charset.mjs +11 -8
  10. package/engine/address-diff.mjs +266 -22
  11. package/engine/anchored-sections.mjs +83 -0
  12. package/engine/anchors.mjs +83 -0
  13. package/engine/base-compiler.mjs +148 -18
  14. package/engine/bundle-notes.mjs +276 -0
  15. package/engine/bundles.mjs +307 -0
  16. package/engine/code-fences.mjs +103 -0
  17. package/engine/compile-corpus.mjs +89 -0
  18. package/engine/content-address.mjs +267 -5
  19. package/engine/content-format-check.mjs +54 -11
  20. package/engine/content-format.mjs +37 -5
  21. package/engine/content-index.mjs +394 -111
  22. package/engine/content-links.mjs +185 -77
  23. package/engine/content-lint.mjs +232 -14
  24. package/engine/content-package.mjs +2 -1
  25. package/engine/content-tables.mjs +99 -3
  26. package/engine/document-subtypes.mjs +49 -6
  27. package/engine/field-reference.mjs +1 -1
  28. package/engine/field-spec.mjs +56 -6
  29. package/engine/folder-notes.mjs +470 -0
  30. package/engine/foreign-catalog.mjs +195 -4
  31. package/engine/{manifest-emit.mjs → foundry-entries.mjs} +78 -81
  32. package/engine/frontmatter-lint.mjs +245 -19
  33. package/engine/frontmatter.mjs +88 -8
  34. package/engine/generate.mjs +304 -13
  35. package/engine/helpers.mjs +293 -64
  36. package/engine/ids.mjs +137 -2
  37. package/engine/index-records.mjs +126 -0
  38. package/engine/index.mjs +23 -5
  39. package/engine/item-compiler.mjs +349 -0
  40. package/engine/item-docs.mjs +7 -1
  41. package/engine/item-registry.mjs +6 -0
  42. package/engine/journals.mjs +93 -27
  43. package/engine/macros.mjs +4 -2
  44. package/engine/metadata-index.mjs +495 -0
  45. package/engine/note-claims.mjs +146 -25
  46. package/engine/note-ids.mjs +112 -0
  47. package/engine/note-renames.mjs +134 -0
  48. package/engine/note-schemas.mjs +25 -0
  49. package/engine/note-vocabulary.mjs +110 -27
  50. package/engine/pack-config.mjs +4 -0
  51. package/engine/pack-router.mjs +23 -0
  52. package/engine/retired-fields.mjs +137 -3
  53. package/engine/scenes.mjs +66 -34
  54. package/engine/schema-check.mjs +58 -17
  55. package/engine/site-build.mjs +71 -12
  56. package/engine/site-index.mjs +20 -7
  57. package/engine/sql-tables.mjs +485 -0
  58. package/engine/subtype-registry.mjs +102 -0
  59. package/engine/system-block.mjs +96 -12
  60. package/engine/systems.mjs +201 -0
  61. package/engine/web-wikilinks.mjs +50 -20
  62. package/engine/wikilink-syntax.mjs +17 -8
  63. package/engine/wikilinks.mjs +124 -51
  64. package/engine/yaml-lint.mjs +282 -0
  65. package/hm3/actors.mjs +352 -0
  66. package/hm3/default-item-art.mjs +75 -0
  67. package/hm3/document-subtypes.mjs +134 -0
  68. package/hm3/index.mjs +56 -0
  69. package/hm3/item-builders.mjs +84 -0
  70. package/hm3/item-fields.mjs +180 -0
  71. package/hm3/items.mjs +96 -0
  72. package/hm3/template-priority.mjs +85 -0
  73. package/labels.mjs +191 -0
  74. package/manifest.mjs +43 -2
  75. package/package.json +19 -4
  76. package/release.mjs +62 -7
  77. package/sohl/actors.mjs +33 -487
  78. package/sohl/being-info.mjs +16 -7
  79. package/sohl/default-item-art.mjs +14 -3
  80. package/sohl/document-subtypes.mjs +16 -10
  81. package/sohl/item-builders.mjs +14 -5
  82. package/sohl/item-fields.mjs +68 -7
  83. package/sohl/items.mjs +44 -258
  84. package/sohl/note-schemas.mjs +2 -2
  85. package/types/content-config.d.mts +21 -42
  86. package/types/engine/actor-compiler.d.mts +204 -0
  87. package/types/engine/address-charset.d.mts +11 -8
  88. package/types/engine/address-diff.d.mts +53 -5
  89. package/types/engine/anchored-sections.d.mts +21 -0
  90. package/types/engine/anchors.d.mts +20 -0
  91. package/types/engine/base-compiler.d.mts +17 -17
  92. package/types/engine/bundle-notes.d.mts +173 -0
  93. package/types/engine/bundles.d.mts +60 -0
  94. package/types/engine/code-fences.d.mts +43 -0
  95. package/types/engine/compile-corpus.d.mts +32 -0
  96. package/types/engine/content-address.d.mts +205 -5
  97. package/types/engine/content-format-check.d.mts +6 -2
  98. package/types/engine/content-format.d.mts +57 -1
  99. package/types/engine/content-index.d.mts +64 -80
  100. package/types/engine/content-links.d.mts +52 -7
  101. package/types/engine/content-lint.d.mts +10 -1
  102. package/types/engine/content-package.d.mts +2 -1
  103. package/types/engine/content-tables.d.mts +21 -39
  104. package/types/engine/document-subtypes.d.mts +37 -3
  105. package/types/engine/field-spec.d.mts +76 -5
  106. package/types/engine/folder-notes.d.mts +159 -0
  107. package/types/engine/foreign-catalog.d.mts +53 -0
  108. package/types/engine/{manifest-emit.d.mts → foundry-entries.d.mts} +16 -38
  109. package/types/engine/frontmatter-lint.d.mts +10 -2
  110. package/types/engine/frontmatter.d.mts +64 -0
  111. package/types/engine/generate.d.mts +38 -0
  112. package/types/engine/helpers.d.mts +94 -30
  113. package/types/engine/ids.d.mts +96 -0
  114. package/types/engine/index-records.d.mts +68 -0
  115. package/types/engine/index.d.mts +9 -3
  116. package/types/engine/item-compiler.d.mts +131 -0
  117. package/types/engine/journals.d.mts +47 -9
  118. package/types/engine/metadata-index.d.mts +226 -0
  119. package/types/engine/note-claims.d.mts +57 -11
  120. package/types/engine/note-ids.d.mts +38 -0
  121. package/types/engine/note-renames.d.mts +102 -0
  122. package/types/engine/note-vocabulary.d.mts +44 -8
  123. package/types/engine/retired-fields.d.mts +75 -0
  124. package/types/engine/scenes.d.mts +3 -2
  125. package/types/engine/schema-check.d.mts +25 -4
  126. package/types/engine/site-build.d.mts +4 -4
  127. package/types/engine/site-index.d.mts +1 -1
  128. package/types/engine/sql-tables.d.mts +185 -0
  129. package/types/engine/subtype-registry.d.mts +49 -0
  130. package/types/engine/system-block.d.mts +40 -1
  131. package/types/engine/systems.d.mts +106 -0
  132. package/types/engine/web-wikilinks.d.mts +4 -2
  133. package/types/engine/wikilink-syntax.d.mts +10 -3
  134. package/types/engine/wikilinks.d.mts +41 -13
  135. package/types/engine/yaml-lint.d.mts +107 -0
  136. package/types/hm3/actors.d.mts +48 -0
  137. package/types/hm3/default-item-art.d.mts +42 -0
  138. package/types/hm3/document-subtypes.d.mts +24 -0
  139. package/types/hm3/index.d.mts +7 -0
  140. package/types/hm3/item-builders.d.mts +11 -0
  141. package/types/hm3/item-fields.d.mts +12 -0
  142. package/types/hm3/items.d.mts +23 -0
  143. package/types/hm3/template-priority.d.mts +21 -0
  144. package/types/manifest.d.mts +22 -1
  145. package/types/release.d.mts +9 -4
  146. package/types/sohl/actors.d.mts +7 -74
  147. package/types/sohl/being-info.d.mts +8 -27
  148. package/types/sohl/default-item-art.d.mts +5 -3
  149. package/types/sohl/items.d.mts +17 -32
  150. package/engine/foreign-manifests.mjs +0 -126
  151. package/engine/kb-manifest.mjs +0 -490
  152. package/types/engine/foreign-manifests.d.mts +0 -43
  153. package/types/engine/kb-manifest.d.mts +0 -241
@@ -1,241 +0,0 @@
1
- /**
2
- * The **canonical** address of a note: fully qualified, one spelling per
3
- * document, and globally unique.
4
- *
5
- * The written form of a link may omit the package (`[[skill-lang]]`), which
6
- * defaults it to the citing note's own. Everything internal — index keys,
7
- * manifest keys, every lookup — uses this instead, so no consumer has to know
8
- * what a short form defaulted to.
9
- *
10
- * Global uniqueness is what lets a foreign manifest merge straight into a local
11
- * index: the keys cannot collide by accident, so a key already present on merge
12
- * is a real conflict rather than an artefact of two packages sharing a
13
- * namespace. `(type, shortcode)` alone is unique only *within* a package, and
14
- * two independently authored packages reaching for the same short string is a
15
- * matter of time (#1499).
16
- *
17
- * @param {string} pkg - The owning **content** package (`sohl`, `thalorna`) —
18
- * not the Foundry package, which varies per compilation target.
19
- * @param {string} type - The note's `type`.
20
- * @param {string} shortcode - The note's `shortcode`.
21
- * @returns {string} `package/type/shortcode`, lowercased.
22
- */
23
- export function canonicalKey(pkg: string, type: string, shortcode: string): string;
24
- /**
25
- * Reads a canonical key back into its parts.
26
- *
27
- * Parsing is plain positional counting: split on the separator, require
28
- * {@link CANONICAL_KEY_SEGMENTS} of them, and assign each position its field.
29
- * **The charset rule is what makes that sound** — every segment is
30
- * `^[A-Za-z0-9]+$` (`ADDRESS_SEGMENT_PATTERN` in `engine/address-charset.mjs`),
31
- * so the hyphen is purely a separator and the count alone determines every
32
- * field. That is enforced at each of the three sources rather than assumed of
33
- * the data: shortcodes by `content-lint.mjs` (#1397), `contentPackage` by
34
- * `defineConfig` (#59), and types are bare words. Were any of them free to
35
- * carry a hyphen, no amount of counting would recover the fields and the reader
36
- * would need a vocabulary to match against instead.
37
- *
38
- * **Nothing to read and nothing readable are different answers.** A key that
39
- * cannot be canonical — `harn-adventures-skill-melee`, four segments — yields
40
- * `null`, while an absent or blank input yields `undefined`. Both are falsy, so
41
- * every call site (all of which test the result for truthiness) is unaffected;
42
- * the distinction is there so a caller reporting "this key is unreadable" can
43
- * tell that it has a key to report about.
44
- *
45
- * @param {unknown} key - A canonical key, or nothing.
46
- * @returns {{package: string, type: string, shortcode: string}|null|undefined}
47
- * The parts; `null` when there is a string that is not in canonical form;
48
- * `undefined` when there is no key at all.
49
- */
50
- export function readCanonicalKey(key: unknown): {
51
- package: string;
52
- type: string;
53
- shortcode: string;
54
- } | null | undefined;
55
- /**
56
- * The package-relative address a site-absolute URL records as.
57
- *
58
- * Strips the emitting package's own base, so what lands in the manifest says
59
- * *where in the package* a page is and nothing about where the package itself
60
- * is mounted. A URL outside the base is an error rather than a best effort: it
61
- * would record an address that silently resolves to the wrong place once a
62
- * consumer prefixes its own base.
63
- *
64
- * @param {string} url - The site-absolute URL the emitting build publishes at.
65
- * @param {string} base - That build's base for the package, e.g. `"/thalorna/"`.
66
- * @returns {string} The address relative to `base`, with no leading slash.
67
- */
68
- export function packageRelative(url: string, base: string): string;
69
- /**
70
- * The URL a package-relative address resolves to in this build.
71
- *
72
- * Plain concatenation, which is what makes an absolute-origin base work: a base
73
- * of `"https://thalorna.example.org/"` yields an absolute link, and one of
74
- * `"/thalorna/"` a root-relative one, with no other rule to keep in step.
75
- *
76
- * @param {string} rel - The package-relative address from a manifest entry.
77
- * @param {string} base - This build's base for that package.
78
- * @returns {string} The resolved URL.
79
- */
80
- export function resolvePackageUrl(rel: string, base: string): string;
81
- /**
82
- * Builds one package's manifest from the KB build's own entries.
83
- *
84
- * Only notes carrying a `shortcode` appear: the shortcode is the stable
85
- * identity another package addresses them by, and a note without one cannot be
86
- * the target of a cross-package link at all.
87
- *
88
- * @param {string} pkg - The package name, e.g. `"sohl"`.
89
- * @param {Array<object>} entries - KB entries (`{ fm, name, url }`).
90
- * @param {string} [base] - Where *this* build serves `pkg`, stripped from each
91
- * entry's URL so the recorded address is package-relative (#1465). Omitted,
92
- * this build publishes no web surface for the package and no entry carries a
93
- * `path` — see below.
94
- * @param {string} [foundryPackage] - The Foundry package this build ships the
95
- * compiled documents in. Given, each entry also carries the `uuid` /
96
- * `docUuid` a pack build resolves against; omitted, the manifest describes
97
- * the web surface only.
98
- * @returns {object} The manifest document.
99
- */
100
- export function buildManifest(pkg: string, entries: Array<object>, base?: string, foundryPackage?: string): object;
101
- /**
102
- * Writes one manifest per package into `dir`.
103
- *
104
- * @param {Map<string, Array<object>>} entriesByPackage - Package → entries.
105
- * @param {string} dir - Output directory; created if absent.
106
- * @param {Record<string, string>} bases - Package → where *this* build serves
107
- * it, which is what each entry's address is recorded relative to. This is the
108
- * emitting build's own layout, not {@link PACKAGE_BASE}: a package's own site
109
- * commonly serves it at `"/"` while a consumer mounts it under a prefix.
110
- * @param {Record<string, string>} [foundryPackages] - Package → the Foundry
111
- * package shipping its documents. Only a package this build publishes can
112
- * have one, since the UUID names where *this* repository ships them.
113
- * @returns {Array<{ package: string, file: string, count: number }>} What was written.
114
- */
115
- export function writeManifests(entriesByPackage: Map<string, Array<object>>, dir: string, bases: Record<string, string>, foundryPackages?: Record<string, string>): Array<{
116
- package: string;
117
- file: string;
118
- count: number;
119
- }>;
120
- /**
121
- * Loads vendored manifests for packages this build does not itself publish.
122
- *
123
- * A package built locally is skipped even if a manifest for it is present: the
124
- * live build is authoritative and a vendored copy of it can only be stale.
125
- *
126
- * Each entry's package-relative address is resolved against this build's base
127
- * for that package (#1465), so what the index holds is a usable `url` and every
128
- * consumer downstream is unchanged by the format.
129
- *
130
- * @param {string} dir - Directory of vendored `<package>.json` manifests.
131
- * @param {Iterable<string>} localPackages - Packages this build publishes.
132
- * @param {Record<string, string>} [bases] - Package → base to resolve against;
133
- * defaults to {@link PACKAGE_BASE}.
134
- * @returns {{ index: Map<string, object>, packages: Set<string>, stale: Array<object> }}
135
- * `index` maps the canonical `package-type-shortcode` → `{ url, name, uuid,
136
- * doc, anchors, type, package }`. Keys are globally unique, so this merges
137
- * directly into a local index with no prefixing and no separate lookup path.
138
- * `url` is `undefined` for an entry with no page (#1516) and `uuid` for one
139
- * that compiles into no document, so a caller must check the address it
140
- * intends to use rather than assume a hit carries it.
141
- */
142
- export function loadForeignManifests(dir: string, localPackages: Iterable<string>, bases?: Record<string, string>): {
143
- index: Map<string, object>;
144
- packages: Set<string>;
145
- stale: Array<object>;
146
- };
147
- /**
148
- * Whether every linkable package is accounted for, locally or by manifest.
149
- *
150
- * This is what gates the dead-link guard. It is deliberately derived from data
151
- * rather than set by a flag: the guard turns itself on the moment the last
152
- * missing manifest appears, instead of waiting for someone to remember.
153
- *
154
- * @param {Iterable<string>} localPackages - Packages this build publishes.
155
- * @param {Iterable<string>} manifestPackages - Packages loaded from manifests.
156
- * @returns {{ complete: boolean, missing: Array<string> }}
157
- */
158
- export function manifestsComplete(localPackages: Iterable<string>, manifestPackages: Iterable<string>): {
159
- complete: boolean;
160
- missing: Array<string>;
161
- };
162
- /**
163
- * Packages that publish a manifest and therefore exchange addresses.
164
- *
165
- * The guard in {@link manifestsComplete} stays off until every one of these is
166
- * accounted for, so adding a package here without also publishing its manifest
167
- * relaxes the build rather than breaking it.
168
- */
169
- export const LINK_PACKAGES: readonly string[];
170
- /**
171
- * How many segments a canonical key has, and therefore how many the reader
172
- * below counts.
173
- *
174
- * Named rather than written as a literal because it is the *grammar*, not an
175
- * implementation detail of one function: it is the number a change to the
176
- * address form would move, and the thing a reader of that change has to find.
177
- *
178
- * @type {number}
179
- */
180
- export const CANONICAL_KEY_SEGMENTS: number;
181
- /**
182
- * Manifest format version.
183
- *
184
- * Bumped to 2 by #1465: entries changed from a site-absolute `url` to a
185
- * package-relative `path`. The two shapes are indistinguishable to a naive
186
- * reader — prefixing a v1 `url` yields `/thalorna/thalorna/…`, which resolves,
187
- * renders, and 404s — so the version is what makes a stale vendored file an
188
- * error rather than a wrong link.
189
- *
190
- * Bumped to 4 by #1499: keys use the authored hyphen separator
191
- * (`sohl-affliction-aconite`) so a key *is* the address an author writes; an
192
- * item's documentation became an entry in its own right
193
- * (`sohl-docaffliction-aconite`) rather than a second field; and entries gained
194
- * `anchors`, mapping a note's named sections to the full UUID each compiled to.
195
- *
196
- * Bumped to 3 by #1499: keys became **canonical** — fully qualified
197
- * `package/type/shortcode` rather than `type/shortcode` — and entries gained the
198
- * Foundry `uuid` / `docUuid` beside the web `path`. A v2 key read as a v3 one
199
- * addresses a package named after a type, so again the version is what turns a
200
- * stale vendored file into an error.
201
- *
202
- * Bumped to 5 by #1516: `path` became optional, so a package that ships
203
- * compendiums and publishes no site can still publish the Foundry addresses of
204
- * its documents — the mirror of an entry that has a `path` and no `uuid`.
205
- */
206
- export const MANIFEST_VERSION: 5;
207
- /**
208
- * Every version this build can read, newest last.
209
- *
210
- * A version exists to stop a file whose values *read differently* from being
211
- * resolved anyway, and that is the only thing it is allowed to gate. Every bump
212
- * so far did change a reading — a v2 key read as a v4 one addresses a package
213
- * named after a type — so each dropped its predecessors. **v5 did not**: it
214
- * only permits an absent `path`, so every v4 value still means exactly what it
215
- * meant, and refusing v4 would make a purely relaxing change a flag day in
216
- * which every package must re-emit on the same afternoon or every build breaks
217
- * (#1516).
218
- *
219
- * The unsafe direction is unchanged and still hard-fails: an older consumer
220
- * meeting a newer file rejects it, because it cannot know what the new shape
221
- * permits. Widening is therefore always safe to do here first and adopt
222
- * elsewhere later.
223
- */
224
- export const READABLE_VERSIONS: readonly number[];
225
- /**
226
- * Where this build serves each package, keyed by package name.
227
- *
228
- * One line per package, and the only edit a relocation requires: point a
229
- * package at another path (`"/setting/thalorna/"`) or another origin
230
- * (`"https://thalorna.example.org/"`) and every inbound link into it follows.
231
- * A base is a prefix, so it must end in `/`.
232
- *
233
- * Only *foreign* packages are consulted — a package this build publishes is
234
- * authoritative in its own entries and never resolves through a manifest — but
235
- * every linkable package is listed, because which are foreign depends on the
236
- * consuming repository and this file is vendored into each of them.
237
- */
238
- export const PACKAGE_BASE: Readonly<{
239
- sohl: "/sohl/";
240
- thalorna: "/thalorna/";
241
- }>;