@heroiclands/package-build 22.3.1 → 22.4.1
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 +65 -0
- package/CONTENT.md +189 -306
- package/bin/content-build.mjs +15 -20
- package/bin/package-build.mjs +87 -3
- package/content-config.mjs +70 -179
- package/docs/api.md +27 -32
- package/docs/commands.md +98 -19
- package/docs/configuration.md +90 -126
- package/docs/content-format.md +25 -15
- package/docs/getting-started.md +5 -4
- package/docs/project-setup.md +1 -1
- package/engine/actor-compiler.mjs +53 -14
- package/engine/changelog-lint.mjs +629 -0
- package/engine/content-links.mjs +25 -60
- package/engine/diagnostics.mjs +2 -2
- package/engine/field-reference.mjs +7 -1
- package/engine/homepage.mjs +91 -172
- package/engine/metadata-index.mjs +7 -3
- package/engine/note-vocabulary.mjs +0 -20
- package/engine/pdf-build.mjs +2 -2
- package/engine/site-build.mjs +64 -225
- package/engine/site-config.mjs +15 -53
- package/engine/site-root.mjs +26 -70
- package/githooks/pre-commit +53 -2
- package/package.json +1 -1
- package/types/content-config.d.mts +6 -8
- package/types/engine/actor-compiler.d.mts +42 -9
- package/types/engine/changelog-lint.d.mts +50 -0
- package/types/engine/content-links.d.mts +12 -23
- package/types/engine/diagnostics.d.mts +2 -2
- package/types/engine/homepage.d.mts +51 -91
- package/types/engine/note-vocabulary.d.mts +0 -12
- package/types/engine/site-build.d.mts +28 -129
- package/types/engine/site-config.d.mts +10 -19
- package/types/engine/site-root.d.mts +11 -36
|
@@ -200,13 +200,39 @@ export function catalogueKey(subType, shortcode, pkg) {
|
|
|
200
200
|
return pkg ? packagedItemAddress(pkg, subType, folded) : itemAddress(subType, folded);
|
|
201
201
|
}
|
|
202
202
|
|
|
203
|
+
/**
|
|
204
|
+
* An item's own shortcode, read off its compiled document.
|
|
205
|
+
*
|
|
206
|
+
* **`system.shortcode`**, where a system's data model declares such a field.
|
|
207
|
+
* Where it does not — HM3's has no such field — the handle instead lives in
|
|
208
|
+
* that system's own flag namespace, `flags.<systemId>.shortcode`: a system
|
|
209
|
+
* writes its per-document handle into its own flags and never another
|
|
210
|
+
* system's, so a document extracted from one system's catalogue is read
|
|
211
|
+
* through that system's namespace and no other. `system.shortcode` wins where
|
|
212
|
+
* both are present.
|
|
213
|
+
*
|
|
214
|
+
* @param {object} doc - A compiled Item document, or an embedded item merged
|
|
215
|
+
* from one.
|
|
216
|
+
* @param {string|null} [systemId] - The system whose catalogue `doc` was read
|
|
217
|
+
* from. Omitted or `null`, only `system.shortcode` is read.
|
|
218
|
+
* @returns {string|undefined} The shortcode, or `undefined` when the document
|
|
219
|
+
* states neither.
|
|
220
|
+
*/
|
|
221
|
+
export function shortcodeOf(doc, systemId = null) {
|
|
222
|
+
const own = doc?.system?.shortcode;
|
|
223
|
+
if (own) return own;
|
|
224
|
+
if (!systemId) return undefined;
|
|
225
|
+
return doc?.flags?.[systemId]?.shortcode;
|
|
226
|
+
}
|
|
227
|
+
|
|
203
228
|
/**
|
|
204
229
|
* What identifies one embedded item on its actor.
|
|
205
230
|
*
|
|
206
|
-
* **Its own
|
|
207
|
-
* merely *selects* the catalogue template the
|
|
208
|
-
* never written to the document. Two daggers
|
|
209
|
-
* embodiments and each must declare its
|
|
231
|
+
* **Its own shortcode** — read by {@link shortcodeOf} — not the entry's
|
|
232
|
+
* top-level `shortcode`, which merely *selects* the catalogue template the
|
|
233
|
+
* entry is written from and is never written to the document. Two daggers
|
|
234
|
+
* may share a selector; they are two embodiments and each must declare its
|
|
235
|
+
* own.
|
|
210
236
|
*
|
|
211
237
|
* The name is a last resort, for a **stand-alone** entry that names no template
|
|
212
238
|
* and states no shortcode. It is a poor identity — presentation, and free to be
|
|
@@ -215,10 +241,13 @@ export function catalogueKey(subType, shortcode, pkg) {
|
|
|
215
241
|
* message says to state a `system.shortcode`.
|
|
216
242
|
*
|
|
217
243
|
* @param {object} item - The merged embedded item.
|
|
244
|
+
* @param {string|null} [systemId] - The system this item's document was
|
|
245
|
+
* compiled or extracted for, so a document whose own data model carries no
|
|
246
|
+
* `system.shortcode` field is still read by its own flag namespace.
|
|
218
247
|
* @returns {string} The identity, for {@link embeddedItemId}.
|
|
219
248
|
*/
|
|
220
|
-
export function embeddedIdentity(item) {
|
|
221
|
-
const own = item
|
|
249
|
+
export function embeddedIdentity(item, systemId = null) {
|
|
250
|
+
const own = shortcodeOf(item, systemId);
|
|
222
251
|
if (typeof own === "string" && own.trim()) return own.trim();
|
|
223
252
|
return typeof item?.name === "string" ? item.name : "";
|
|
224
253
|
}
|
|
@@ -253,9 +282,9 @@ export function embeddedItemId(actorId, subType, identity) {
|
|
|
253
282
|
/**
|
|
254
283
|
* Load every JSON file under each of `itemsSourceDirs`, returning one Map keyed
|
|
255
284
|
* by {@link itemAddress} — the compiled document's **subtype** and its
|
|
256
|
-
*
|
|
257
|
-
* The `_key` field is stripped from each entry — it is
|
|
258
|
-
* data model.
|
|
285
|
+
* shortcode, read by {@link shortcodeOf}. Folder docs and entries without a
|
|
286
|
+
* shortcode are skipped. The `_key` field is stripped from each entry — it is
|
|
287
|
+
* not part of the item data model.
|
|
259
288
|
*
|
|
260
289
|
* The directories are read as one address space, because an actor names an item
|
|
261
290
|
* by `(type, shortcode)` and never by the pack it happens to ship in. Two local
|
|
@@ -269,12 +298,22 @@ export function embeddedItemId(actorId, subType, identity) {
|
|
|
269
298
|
* colliding with it. Local directories are therefore read first, and anything
|
|
270
299
|
* already claimed is left alone.
|
|
271
300
|
*
|
|
301
|
+
* **Each foreign directory reads its own flag namespace.** A foreign entry's
|
|
302
|
+
* `package` is the system whose catalogue it was extracted from, and that is
|
|
303
|
+
* the only namespace {@link shortcodeOf} is asked to fall back to for it — a
|
|
304
|
+
* document carrying another system's flag, sitting in this system's catalogue,
|
|
305
|
+
* is exactly the defect a system writing outside its own namespace produces,
|
|
306
|
+
* and is silently skipped rather than resolved.
|
|
307
|
+
*
|
|
272
308
|
* @param {readonly string[]} itemsSourceDirs - Every local Item pack's JSON tree.
|
|
273
309
|
* @param {readonly string[]} [foreignSourceDirs] - Extracted dependency
|
|
274
310
|
* catalogues, consulted only for addresses no local pack defines.
|
|
311
|
+
* @param {string|null} [system] - The system `itemsSourceDirs` were compiled
|
|
312
|
+
* for, so a local document whose data model carries no `system.shortcode`
|
|
313
|
+
* field is still read by its own flag namespace.
|
|
275
314
|
* @returns {Map<string, object>} The predefined items, by address.
|
|
276
315
|
*/
|
|
277
|
-
export function loadItemsMap(itemsSourceDirs, foreignSourceDirs = []) {
|
|
316
|
+
export function loadItemsMap(itemsSourceDirs, foreignSourceDirs = [], system = null) {
|
|
278
317
|
const map = new Map();
|
|
279
318
|
const source = new Map();
|
|
280
319
|
const shadowed = [];
|
|
@@ -307,7 +346,7 @@ export function loadItemsMap(itemsSourceDirs, foreignSourceDirs = []) {
|
|
|
307
346
|
});
|
|
308
347
|
continue;
|
|
309
348
|
}
|
|
310
|
-
const shortcode = doc
|
|
349
|
+
const shortcode = shortcodeOf(doc, system);
|
|
311
350
|
if (!doc?.type || !shortcode) continue;
|
|
312
351
|
const address = catalogueKey(doc.type, shortcode);
|
|
313
352
|
const owner = source.get(address);
|
|
@@ -349,7 +388,7 @@ export function loadItemsMap(itemsSourceDirs, foreignSourceDirs = []) {
|
|
|
349
388
|
});
|
|
350
389
|
continue;
|
|
351
390
|
}
|
|
352
|
-
const shortcode = doc
|
|
391
|
+
const shortcode = shortcodeOf(doc, foreignPackage);
|
|
353
392
|
if (!doc?.type || !shortcode) continue;
|
|
354
393
|
const address = catalogueKey(doc.type, shortcode);
|
|
355
394
|
// eslint-disable-next-line no-unused-vars
|
|
@@ -574,7 +613,7 @@ export class SystemActorCompiler extends BasePackCompiler {
|
|
|
574
613
|
*/
|
|
575
614
|
async prepare() {
|
|
576
615
|
await super.prepare();
|
|
577
|
-
this.itemsMap = loadItemsMap(this.itemsSourceDirs, this.foreignSourceDirs);
|
|
616
|
+
this.itemsMap = loadItemsMap(this.itemsSourceDirs, this.foreignSourceDirs, this.system);
|
|
578
617
|
log.info(`Loaded ${this.itemsMap.size} predefined items for actor resolution`);
|
|
579
618
|
}
|
|
580
619
|
|
|
@@ -787,7 +826,7 @@ export class SystemActorCompiler extends BasePackCompiler {
|
|
|
787
826
|
// ships blank on purpose rather than collecting a default.
|
|
788
827
|
merged.img =
|
|
789
828
|
this.artPath(overlay ?? {}, "icon") ?? merged.img ?? itemArt(type, this.system);
|
|
790
|
-
const identity = embeddedIdentity(merged);
|
|
829
|
+
const identity = embeddedIdentity(merged, this.system);
|
|
791
830
|
const claim = `${actorId}\u0000${itemAddress(/** @type {string} */ (subType), identity)}`;
|
|
792
831
|
const first = this.#embeddedClaims.get(claim);
|
|
793
832
|
if (first !== undefined) {
|