@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.
- package/CHANGELOG.md +1773 -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 +394 -111
- 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} +78 -81
- 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/labels.mjs +191 -0
- package/manifest.mjs +43 -2
- package/package.json +19 -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 +64 -80
- 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} +16 -38
- 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
package/engine/journals.mjs
CHANGED
|
@@ -45,10 +45,11 @@
|
|
|
45
45
|
|
|
46
46
|
import log from "loglevel";
|
|
47
47
|
|
|
48
|
-
import { sohlField, makeId, resolveName, defaultStats, md } from "./helpers.mjs";
|
|
48
|
+
import { sohlField, makeId, resolveName, defaultStats, md, folderField } from "./helpers.mjs";
|
|
49
49
|
import { BasePackCompiler } from "./base-compiler.mjs";
|
|
50
50
|
import { anchorPageId } from "./wikilinks.mjs";
|
|
51
51
|
import { hasDocEntry, itemDocEntryId } from "./item-docs.mjs";
|
|
52
|
+
import { JOURNAL_TYPES } from "./ids.mjs";
|
|
52
53
|
|
|
53
54
|
/**
|
|
54
55
|
* Splits a markdown body into pages by top-level H1 headings. Fenced
|
|
@@ -129,45 +130,91 @@ export function splitPages(body, leadName = "Introduction") {
|
|
|
129
130
|
}
|
|
130
131
|
|
|
131
132
|
/**
|
|
132
|
-
* Two
|
|
133
|
-
*
|
|
134
|
-
*
|
|
133
|
+
* Two pages in one note that would derive the same id, which the LevelDB packer
|
|
134
|
+
* reports only as an opaque duplicate-key collision. Catch it here, where the
|
|
135
|
+
* note and the page can be named.
|
|
135
136
|
*
|
|
136
|
-
*
|
|
137
|
+
* Both halves of {@link journalPageId} are checked, because each is now keyed
|
|
138
|
+
* on an identity alone:
|
|
139
|
+
*
|
|
140
|
+
* - **An anchor**, declared twice, has always collided.
|
|
141
|
+
* - **A name**, repeated among the unanchored pages, collides since #268 took
|
|
142
|
+
* the index out of the key. `MD024` with `siblings_only` already makes two
|
|
143
|
+
* sibling headings with the same text a lint error, so this is the same rule
|
|
144
|
+
* restated where the build can enforce it — a lint is a separate command, and
|
|
145
|
+
* the compile must not depend on someone having run it.
|
|
146
|
+
*
|
|
147
|
+
* The two are counted separately: an anchored page takes its id from the slug
|
|
148
|
+
* and an unanchored one from the name, so a page named for another's anchor is
|
|
149
|
+
* not a collision.
|
|
150
|
+
*
|
|
151
|
+
* @param {Array<{anchorSlug: string|null, name: string}>} rawPages - From
|
|
152
|
+
* {@link splitPages}.
|
|
137
153
|
* @param {string} noteName - The note, for the error message.
|
|
138
|
-
* @throws {Error} When
|
|
154
|
+
* @throws {Error} When two pages in one note share an anchor or a name.
|
|
139
155
|
*/
|
|
140
|
-
export function
|
|
141
|
-
const
|
|
156
|
+
export function assertUniquePages(rawPages, noteName) {
|
|
157
|
+
const anchors = new Set();
|
|
158
|
+
const names = new Set();
|
|
142
159
|
for (const page of rawPages) {
|
|
143
|
-
if (
|
|
144
|
-
|
|
160
|
+
if (page.anchorSlug) {
|
|
161
|
+
if (anchors.has(page.anchorSlug)) {
|
|
162
|
+
throw new Error(
|
|
163
|
+
`note "${noteName}" declares the anchor {#${page.anchorSlug}} on more than one heading; an anchor must be unique within its note`,
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
anchors.add(page.anchorSlug);
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
if (names.has(page.name)) {
|
|
145
170
|
throw new Error(
|
|
146
|
-
`note "${noteName}"
|
|
171
|
+
`note "${noteName}" has more than one page named "${page.name}"; a page is identified by its heading, so the two would compile to one document — rename one, or give it an {#anchor}`,
|
|
147
172
|
);
|
|
148
173
|
}
|
|
149
|
-
|
|
174
|
+
names.add(page.name);
|
|
150
175
|
}
|
|
151
176
|
}
|
|
152
177
|
|
|
178
|
+
/**
|
|
179
|
+
* The anchor half of {@link assertUniquePages}, under its former name.
|
|
180
|
+
*
|
|
181
|
+
* @deprecated Call {@link assertUniquePages}, which checks page names too.
|
|
182
|
+
* @param {Array<{anchorSlug: string|null, name: string}>} rawPages - From
|
|
183
|
+
* {@link splitPages}.
|
|
184
|
+
* @param {string} noteName - The note, for the error message.
|
|
185
|
+
*/
|
|
186
|
+
export function assertUniqueAnchors(rawPages, noteName) {
|
|
187
|
+
assertUniquePages(rawPages, noteName);
|
|
188
|
+
}
|
|
189
|
+
|
|
153
190
|
/**
|
|
154
191
|
* The id of one page within its entry.
|
|
155
192
|
*
|
|
156
193
|
* An anchored page takes the id its inbound links compute from the note id and
|
|
157
194
|
* the slug, so link and page agree without shared state. Every other page is
|
|
158
|
-
* keyed by its
|
|
159
|
-
*
|
|
195
|
+
* keyed by its **name**, which is what lets the items pass address an item
|
|
196
|
+
* doc's first page without having compiled it (see
|
|
160
197
|
* {@link sohl.utils.packs.itemDocPointer}).
|
|
161
198
|
*
|
|
199
|
+
* **It takes no index** (#268). A page used to be keyed by position *and* name,
|
|
200
|
+
* so inserting a heading renumbered every page after it and a re-import created
|
|
201
|
+
* new pages beside the old ones — while nothing about those pages had changed.
|
|
202
|
+
* The anchored case above never took one, and is the shape this now shares.
|
|
203
|
+
*
|
|
204
|
+
* The name is a sound identity here in a way it is not for an embedded item: a
|
|
205
|
+
* page's name is its heading, and `MD024` with `siblings_only` is in the shared
|
|
206
|
+
* markdownlint rule set, so two sibling headings with the same text are already
|
|
207
|
+
* a lint error. {@link assertUniquePages} states the same thing at compile
|
|
208
|
+
* time, where the packer would otherwise report only an opaque duplicate key.
|
|
209
|
+
*
|
|
162
210
|
* @param {string} entryId - The owning JournalEntry's `_id`.
|
|
163
211
|
* @param {{anchorSlug: string|null, name: string}} page - From {@link splitPages}.
|
|
164
|
-
* @param {number} index - The page's position in the entry.
|
|
165
212
|
* @returns {string} A 16-character Foundry id.
|
|
166
213
|
*/
|
|
167
|
-
export function journalPageId(entryId, page
|
|
214
|
+
export function journalPageId(entryId, page) {
|
|
168
215
|
return page.anchorSlug ?
|
|
169
216
|
anchorPageId(entryId, page.anchorSlug)
|
|
170
|
-
: makeId("journal-page", `${entryId}:${
|
|
217
|
+
: makeId("journal-page", `${entryId}:${page.name}`);
|
|
171
218
|
}
|
|
172
219
|
|
|
173
220
|
/**
|
|
@@ -188,9 +235,9 @@ export function buildPages(rawPages, entryId, noteName) {
|
|
|
188
235
|
`note "${noteName}" has no Introduction content and no H1 headings — nothing to compile`,
|
|
189
236
|
);
|
|
190
237
|
}
|
|
191
|
-
|
|
192
|
-
return rawPages.map((page
|
|
193
|
-
const pageId = journalPageId(entryId, page
|
|
238
|
+
assertUniquePages(rawPages, noteName);
|
|
239
|
+
return rawPages.map((page) => {
|
|
240
|
+
const pageId = journalPageId(entryId, page);
|
|
194
241
|
return {
|
|
195
242
|
_id: pageId,
|
|
196
243
|
name: page.name,
|
|
@@ -278,15 +325,21 @@ export class Journals extends BasePackCompiler {
|
|
|
278
325
|
* (#1348); a macro's is the same arrangement (#1514), and so is a map's,
|
|
279
326
|
* whose prose is the place description its pins point at (#1525).
|
|
280
327
|
*
|
|
281
|
-
*
|
|
282
|
-
* {@link
|
|
283
|
-
*
|
|
328
|
+
* Two memberships, and they mean different things.
|
|
329
|
+
* {@link module:engine/ids.JOURNAL_TYPES} is the types whose whole document
|
|
330
|
+
* *is* a journal — `doc`, and since #241 `place`, `lore` and `scenario`,
|
|
331
|
+
* which the content format has always described and nothing compiled.
|
|
332
|
+
* {@link sohl.utils.packs.docEntryTypes}, read through
|
|
333
|
+
* {@link sohl.utils.packs.hasDocEntry}, is the types whose prose becomes a
|
|
334
|
+
* journal *beside* another document. The second is the one the link
|
|
335
|
+
* manifest also reads, so what compiles and what is published cannot drift
|
|
336
|
+
* apart; the first has no second document to point at.
|
|
284
337
|
*
|
|
285
338
|
* @param {object} fm - The note's frontmatter.
|
|
286
|
-
* @returns {boolean} True for a
|
|
339
|
+
* @returns {boolean} True for a journal-only note or a doc-carrying one.
|
|
287
340
|
*/
|
|
288
341
|
selects(fm) {
|
|
289
|
-
return fm.type
|
|
342
|
+
return JOURNAL_TYPES.has(String(fm.type)) || hasDocEntry(fm.type);
|
|
290
343
|
}
|
|
291
344
|
|
|
292
345
|
/**
|
|
@@ -333,8 +386,21 @@ export class Journals extends BasePackCompiler {
|
|
|
333
386
|
// against this pack's own folders.yaml — an item folder is declared in
|
|
334
387
|
// the items one, a macro folder in the macros one, and a map's in the
|
|
335
388
|
// scenes one.
|
|
336
|
-
const
|
|
337
|
-
|
|
389
|
+
const { value: authoredFolder, isAddress } = folderField(fm);
|
|
390
|
+
// An address is resolved wherever it is written, including here — and
|
|
391
|
+
// resolving it *here* is what cures the defect this comment used to
|
|
392
|
+
// describe. A folder note has one definition and one address, so the
|
|
393
|
+
// journals pack materialises the very folder the items pack does, by
|
|
394
|
+
// the same id (#257). There is no second folder file left to disagree
|
|
395
|
+
// with the first, and so no arrangement to assume: the mirroring
|
|
396
|
+
// failure is unrepresentable rather than merely reported.
|
|
397
|
+
//
|
|
398
|
+
// `folder:` is unchanged, and still crosses packs verbatim on the
|
|
399
|
+
// assumption both declare it — the arrangement #260 retires.
|
|
400
|
+
const folder =
|
|
401
|
+
isAddress ? this.folderResolver(authoredFolder, { isAddress: true })
|
|
402
|
+
: ownsDoc ? authoredFolder
|
|
403
|
+
: this.folderResolver(authoredFolder);
|
|
338
404
|
|
|
339
405
|
return buildJournalEntry({
|
|
340
406
|
id,
|
package/engine/macros.mjs
CHANGED
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
|
|
52
52
|
import log from "loglevel";
|
|
53
53
|
|
|
54
|
-
import { sohlField, resolveName, resolveImg, defaultStats } from "./helpers.mjs";
|
|
54
|
+
import { sohlField, resolveName, resolveImg, defaultStats, folderField } from "./helpers.mjs";
|
|
55
55
|
import { BasePackCompiler } from "./base-compiler.mjs";
|
|
56
56
|
import { splitPages } from "./journals.mjs";
|
|
57
57
|
|
|
@@ -315,7 +315,9 @@ export class Macros extends BasePackCompiler {
|
|
|
315
315
|
const name = resolveName(fm);
|
|
316
316
|
return buildMacroEntry(fm, {
|
|
317
317
|
command: macroCommand(body, name),
|
|
318
|
-
folder: this.folderResolver(
|
|
318
|
+
folder: this.folderResolver(folderField(fm).value, {
|
|
319
|
+
isAddress: folderField(fm).isAddress,
|
|
320
|
+
}),
|
|
319
321
|
// This pack's system, not the package-wide one (#48).
|
|
320
322
|
stats: this.stats,
|
|
321
323
|
});
|