@heroiclands/package-build 22.9.1 → 22.10.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 +54 -0
- package/CONTENT.md +33 -0
- package/bin/content-build.mjs +3 -1
- package/docs/api.md +10 -6
- package/docs/content-format.md +384 -200
- package/docs/project-setup.md +23 -0
- package/engine/actor-compiler.mjs +20 -7
- package/engine/address-fields.mjs +404 -0
- package/engine/address-values.mjs +80 -0
- package/engine/address.mjs +769 -0
- package/engine/art-fields.mjs +112 -97
- package/engine/art-slots.mjs +81 -0
- package/engine/base-compiler.mjs +59 -7
- package/engine/bundle-notes.mjs +5 -2
- package/engine/bundles.mjs +17 -10
- package/engine/content-address.mjs +23 -186
- package/engine/content-embeds.mjs +18 -4
- package/engine/content-format-check.mjs +50 -22
- package/engine/content-index.mjs +85 -43
- package/engine/content-links.mjs +105 -104
- package/engine/content-lint.mjs +11 -1
- package/engine/content-tables.mjs +9 -1
- package/engine/field-spec.mjs +20 -4
- package/engine/folder-notes.mjs +44 -15
- package/engine/foundry-entries.mjs +3 -0
- package/engine/frontmatter-lint.mjs +144 -43
- package/engine/frontmatter.mjs +55 -10
- package/engine/generate.mjs +7 -1
- package/engine/helpers.mjs +37 -9
- package/engine/holdings.mjs +41 -12
- package/engine/index-records.mjs +2 -0
- package/engine/infobox-render.mjs +2 -1
- package/engine/infobox.mjs +26 -6
- package/engine/item-compiler.mjs +5 -0
- package/engine/item-docs.mjs +7 -44
- package/engine/map-dot.mjs +2 -0
- package/engine/map-notes.mjs +7 -2
- package/engine/map-places.mjs +42 -10
- package/engine/metadata-index.mjs +60 -5
- package/engine/note-addresses.mjs +310 -0
- package/engine/note-vocabulary.mjs +145 -26
- package/engine/pdf-build.mjs +1 -1
- package/engine/pdf-toc.mjs +17 -2
- package/engine/place-relations.mjs +160 -50
- package/engine/populations.mjs +17 -9
- package/engine/reference-targets.mjs +54 -0
- package/engine/scenes.mjs +5 -2
- package/engine/shortcode-references.mjs +68 -0
- package/engine/site-build.mjs +39 -15
- package/engine/site-index.mjs +57 -75
- package/engine/sql-tables.mjs +43 -9
- package/engine/system-block.mjs +21 -0
- package/engine/system-vocabulary.mjs +46 -0
- package/engine/web-wikilinks.mjs +11 -9
- package/engine/wikilink-syntax.mjs +21 -0
- package/engine/wikilinks.mjs +92 -306
- package/githooks/attribution.mjs +82 -0
- package/githooks/commit-message.mjs +26 -0
- package/githooks/commit-msg +3 -35
- package/hm3/actors.mjs +8 -24
- package/hm3/item-fields.mjs +15 -5
- package/package.json +1 -1
- package/sohl/infobox.mjs +80 -17
- package/sohl/item-fields.mjs +114 -41
- package/types/engine/address-fields.d.mts +90 -0
- package/types/engine/address-values.d.mts +34 -0
- package/types/engine/address.d.mts +452 -0
- package/types/engine/art-fields.d.mts +59 -53
- package/types/engine/art-slots.d.mts +40 -0
- package/types/engine/base-compiler.d.mts +24 -2
- package/types/engine/bundle-notes.d.mts +2 -2
- package/types/engine/content-address.d.mts +3 -139
- package/types/engine/content-embeds.d.mts +1 -1
- package/types/engine/content-format-check.d.mts +25 -0
- package/types/engine/content-index.d.mts +2 -2
- package/types/engine/content-links.d.mts +6 -5
- package/types/engine/field-spec.d.mts +44 -9
- package/types/engine/folder-notes.d.mts +11 -10
- package/types/engine/frontmatter-lint.d.mts +7 -97
- package/types/engine/frontmatter.d.mts +16 -1
- package/types/engine/helpers.d.mts +2 -2
- package/types/engine/infobox.d.mts +6 -0
- package/types/engine/item-docs.d.mts +1 -35
- package/types/engine/map-notes.d.mts +2 -2
- package/types/engine/note-addresses.d.mts +41 -0
- package/types/engine/note-vocabulary.d.mts +20 -3
- package/types/engine/place-relations.d.mts +12 -1
- package/types/engine/populations.d.mts +17 -2
- package/types/engine/reference-targets.d.mts +9 -0
- package/types/engine/shortcode-references.d.mts +14 -0
- package/types/engine/site-build.d.mts +3 -3
- package/types/engine/site-index.d.mts +9 -30
- package/types/engine/sql-tables.d.mts +2 -2
- package/types/engine/system-block.d.mts +17 -0
- package/types/engine/system-vocabulary.d.mts +16 -0
- package/types/engine/wikilink-syntax.d.mts +7 -0
- package/types/engine/wikilinks.d.mts +6 -109
- package/types/hm3/item-fields.d.mts +5 -0
- package/types/sohl/infobox.d.mts +4 -5
- package/types/sohl/item-fields.d.mts +8 -0
package/sohl/item-fields.mjs
CHANGED
|
@@ -35,6 +35,7 @@
|
|
|
35
35
|
* @module
|
|
36
36
|
*/
|
|
37
37
|
|
|
38
|
+
import { isAddressTuple } from "../engine/address.mjs";
|
|
38
39
|
import {
|
|
39
40
|
AS_AUTHORED,
|
|
40
41
|
BLANK_IS_DEFAULT,
|
|
@@ -143,14 +144,48 @@ const SKILL_APTITUDES = Object.freeze({
|
|
|
143
144
|
read: (_raw, { fm }) => resolveSkillAptitudes(fm, noteContext(fm, "mystery")),
|
|
144
145
|
});
|
|
145
146
|
|
|
147
|
+
/* --------------------------------------------------------------------- */
|
|
148
|
+
/* The Address positions */
|
|
149
|
+
/* --------------------------------------------------------------------- */
|
|
150
|
+
|
|
151
|
+
/*
|
|
152
|
+
* An affiliation names other notes in four of its fields, and each of those
|
|
153
|
+
* values is an **Address** — written at whatever length says what it means —
|
|
154
|
+
* while the compiled Item holds the **Shortcode** the runtime resolves among
|
|
155
|
+
* one actor's items. `engine/address-fields.mjs` is the step between them, and
|
|
156
|
+
* these are the positions it reads.
|
|
157
|
+
*
|
|
158
|
+
* Each states two things, and they are not the same statement: `type` is the
|
|
159
|
+
* default an omitted `<type>` segment takes, and `accepts` is the set of types
|
|
160
|
+
* the field takes at all. They coincide at all four, which is the common case
|
|
161
|
+
* rather than the rule — an art slot defaults to `icon` and accepts `icon` or
|
|
162
|
+
* `image` — so each is written out rather than derived from the other.
|
|
163
|
+
*/
|
|
164
|
+
|
|
165
|
+
/** One place: an affiliation's seat. */
|
|
166
|
+
const PLACE_VALUE = Object.freeze({ type: "place", accepts: Object.freeze(["place"]) });
|
|
167
|
+
|
|
168
|
+
/** A list of places: the ones an affiliation holds sway over. */
|
|
169
|
+
const PLACE_ITEMS = Object.freeze({ ...PLACE_VALUE, holds: "items" });
|
|
170
|
+
|
|
171
|
+
/** A list of affiliations: the ones this affiliation answers to. */
|
|
172
|
+
const AFFILIATION_ITEMS = Object.freeze({
|
|
173
|
+
type: "affiliation",
|
|
174
|
+
accepts: Object.freeze(["affiliation"]),
|
|
175
|
+
holds: "items",
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
/** A map keyed by affiliation: this one's standing toward each. */
|
|
179
|
+
const AFFILIATION_KEYS = Object.freeze({ ...AFFILIATION_ITEMS, holds: "keys" });
|
|
180
|
+
|
|
146
181
|
/** Standings toward other affiliations, validated against the closed list. */
|
|
147
182
|
const RELATION = Object.freeze({
|
|
148
|
-
shape: "map of affiliation
|
|
183
|
+
shape: "map of affiliation address → standing",
|
|
149
184
|
read: (_raw, { fm }) => resolveRelation(fm, noteContext(fm, "affiliation")),
|
|
150
185
|
});
|
|
151
186
|
|
|
152
187
|
/**
|
|
153
|
-
* A list of references, each
|
|
188
|
+
* A list of references, each an address.
|
|
154
189
|
*
|
|
155
190
|
* Blank entries are dropped rather than emitted: a list that has been edited
|
|
156
191
|
* down in a property editor keeps its empty rows, and an empty string is not a
|
|
@@ -158,15 +193,15 @@ const RELATION = Object.freeze({
|
|
|
158
193
|
* value here — a sovereign polity is subordinate to nobody — rather than an
|
|
159
194
|
* unset one.
|
|
160
195
|
*/
|
|
161
|
-
const
|
|
162
|
-
shape: "list of
|
|
196
|
+
const ADDRESS_LIST = Object.freeze({
|
|
197
|
+
shape: "list of addresses",
|
|
163
198
|
kind: "list",
|
|
164
199
|
read: (raw) =>
|
|
165
200
|
(Array.isArray(raw) ? raw
|
|
166
201
|
: raw == null || raw === "" ? []
|
|
167
202
|
: [raw]
|
|
168
203
|
)
|
|
169
|
-
.map((entry) => String(entry ?? "").trim())
|
|
204
|
+
.map((entry) => (isAddressTuple(entry) ? entry : String(entry ?? "").trim()))
|
|
170
205
|
.filter((entry) => entry !== ""),
|
|
171
206
|
});
|
|
172
207
|
|
|
@@ -237,7 +272,8 @@ const GEAR_COMMON = Object.freeze([
|
|
|
237
272
|
describe: "How many the stack holds. A compendium article ships one.",
|
|
238
273
|
},
|
|
239
274
|
{
|
|
240
|
-
name: "weight",
|
|
275
|
+
name: "data.weight",
|
|
276
|
+
legacyKey: "weight",
|
|
241
277
|
to: "weightBase",
|
|
242
278
|
...AS_AUTHORED,
|
|
243
279
|
kind: "number",
|
|
@@ -245,7 +281,8 @@ const GEAR_COMMON = Object.freeze([
|
|
|
245
281
|
describe: "Weight of one, in pounds.",
|
|
246
282
|
},
|
|
247
283
|
{
|
|
248
|
-
name: "value",
|
|
284
|
+
name: "data.value",
|
|
285
|
+
legacyKey: "value",
|
|
249
286
|
to: "valueBase",
|
|
250
287
|
...AS_AUTHORED,
|
|
251
288
|
kind: "number",
|
|
@@ -253,7 +290,8 @@ const GEAR_COMMON = Object.freeze([
|
|
|
253
290
|
describe: "Worth of one, in pence.",
|
|
254
291
|
},
|
|
255
292
|
{
|
|
256
|
-
name: "quality",
|
|
293
|
+
name: "data.quality",
|
|
294
|
+
legacyKey: "quality",
|
|
257
295
|
to: "qualityBase",
|
|
258
296
|
...AS_AUTHORED,
|
|
259
297
|
kind: "number",
|
|
@@ -261,7 +299,8 @@ const GEAR_COMMON = Object.freeze([
|
|
|
261
299
|
describe: "Craftsmanship, as a modifier to what the article does.",
|
|
262
300
|
},
|
|
263
301
|
{
|
|
264
|
-
name: "durability",
|
|
302
|
+
name: "data.durability",
|
|
303
|
+
legacyKey: "durability",
|
|
265
304
|
to: "durabilityBase",
|
|
266
305
|
...AS_AUTHORED,
|
|
267
306
|
kind: "number",
|
|
@@ -293,6 +332,14 @@ const GEAR_COMMON = Object.freeze([
|
|
|
293
332
|
* Every item type's frontmatter vocabulary, in the order the `system` block
|
|
294
333
|
* emits it.
|
|
295
334
|
*
|
|
335
|
+
* **A field whose shared source is a path into `data:` names both positions.**
|
|
336
|
+
* `name` is the source the content format's mapping tables state — `data.seat`,
|
|
337
|
+
* `data.weight` — and `legacyKey` is the key the system block still carries, which
|
|
338
|
+
* wins while a tree writes it. Naming only the source would move the in-block
|
|
339
|
+
* read to a key spelled `data.seat`, which nothing authors; naming only the key
|
|
340
|
+
* leaves the container the specification points at unread, and the field then
|
|
341
|
+
* compiles its default over an authored value with nothing said.
|
|
342
|
+
*
|
|
296
343
|
* @type {Readonly<Record<string, readonly import("../engine/field-spec.mjs").FieldSpec[]>>}
|
|
297
344
|
*/
|
|
298
345
|
export const ITEM_FIELDS = Object.freeze({
|
|
@@ -341,9 +388,11 @@ export const ITEM_FIELDS = Object.freeze({
|
|
|
341
388
|
{
|
|
342
389
|
// Plural because the field holds a map of many standings, one per
|
|
343
390
|
// affiliation — the singular reads as a misnomer.
|
|
344
|
-
name: "relations",
|
|
391
|
+
name: "data.relations",
|
|
392
|
+
legacyKey: "relations",
|
|
345
393
|
to: "relations",
|
|
346
394
|
...RELATION,
|
|
395
|
+
address: AFFILIATION_KEYS,
|
|
347
396
|
default: {},
|
|
348
397
|
describe: "How this society regards others: aligned, unaligned, rival or nemesis.",
|
|
349
398
|
},
|
|
@@ -351,21 +400,25 @@ export const ITEM_FIELDS = Object.freeze({
|
|
|
351
400
|
// The organisational relation: which bodies this one answers to.
|
|
352
401
|
// A list, because an affiliation may sit under more than one at
|
|
353
402
|
// once — an arcane tradition within an order, say.
|
|
354
|
-
name: "parents",
|
|
403
|
+
name: "data.parents",
|
|
404
|
+
legacyKey: "parents",
|
|
355
405
|
to: "parents",
|
|
356
|
-
...
|
|
406
|
+
...ADDRESS_LIST,
|
|
407
|
+
address: AFFILIATION_ITEMS,
|
|
357
408
|
default: [],
|
|
358
|
-
describe: "Affiliations this one is subordinate to, by
|
|
409
|
+
describe: "Affiliations this one is subordinate to, by address.",
|
|
359
410
|
},
|
|
360
411
|
{
|
|
361
412
|
// Not `capital` or `headquarters`: each fits about half the eleven
|
|
362
413
|
// subTypes, while a seat covers a polity, a guild, an order and a
|
|
363
414
|
// faith alike.
|
|
364
|
-
name: "seat",
|
|
415
|
+
name: "data.seat",
|
|
416
|
+
legacyKey: "seat",
|
|
365
417
|
to: "seat",
|
|
366
418
|
...BLANK_IS_NULL,
|
|
419
|
+
address: PLACE_VALUE,
|
|
367
420
|
default: null,
|
|
368
|
-
describe: "Where the affiliation's authority sits, by place
|
|
421
|
+
describe: "Where the affiliation's authority sits, by place address.",
|
|
369
422
|
},
|
|
370
423
|
{
|
|
371
424
|
// The geographic relation, kept apart from the organisational one
|
|
@@ -375,11 +428,13 @@ export const ITEM_FIELDS = Object.freeze({
|
|
|
375
428
|
// mapping row states (`data.domains` → `system.domain`). The two
|
|
376
429
|
// spellings are deliberate rather than a slip, so the declaration
|
|
377
430
|
// carries both rather than either side guessing.
|
|
378
|
-
name: "domains",
|
|
431
|
+
name: "data.domains",
|
|
432
|
+
legacyKey: "domains",
|
|
379
433
|
to: "domain",
|
|
380
|
-
...
|
|
434
|
+
...ADDRESS_LIST,
|
|
435
|
+
address: PLACE_ITEMS,
|
|
381
436
|
default: [],
|
|
382
|
-
describe: "Places this affiliation holds sway over, by
|
|
437
|
+
describe: "Places this affiliation holds sway over, by address.",
|
|
383
438
|
},
|
|
384
439
|
]),
|
|
385
440
|
|
|
@@ -418,14 +473,16 @@ export const ITEM_FIELDS = Object.freeze({
|
|
|
418
473
|
describe: "How readily the host throws it off.",
|
|
419
474
|
},
|
|
420
475
|
{
|
|
421
|
-
name: "contagionIndex",
|
|
476
|
+
name: "data.contagionIndex",
|
|
477
|
+
legacyKey: "contagionIndex",
|
|
422
478
|
to: "contagionIndexBase",
|
|
423
479
|
...NUMBER,
|
|
424
480
|
default: 0,
|
|
425
481
|
describe: "How readily it passes to someone else.",
|
|
426
482
|
},
|
|
427
483
|
{
|
|
428
|
-
name: "transmission",
|
|
484
|
+
name: "data.transmission",
|
|
485
|
+
legacyKey: "transmission",
|
|
429
486
|
to: "transmission",
|
|
430
487
|
...AS_AUTHORED,
|
|
431
488
|
default: "none",
|
|
@@ -440,7 +497,8 @@ export const ITEM_FIELDS = Object.freeze({
|
|
|
440
497
|
"Days from contracting to onset, rolled by the receiving actor. Unset means no incubation.",
|
|
441
498
|
},
|
|
442
499
|
{
|
|
443
|
-
name: "outcome",
|
|
500
|
+
name: "data.outcome",
|
|
501
|
+
legacyKey: "outcome",
|
|
444
502
|
to: "outcome",
|
|
445
503
|
...BLANK_IS_DEFAULT,
|
|
446
504
|
default: "cured",
|
|
@@ -464,7 +522,8 @@ export const ITEM_FIELDS = Object.freeze({
|
|
|
464
522
|
// cannot be grepped, and each phase's prose differs anyway — which is
|
|
465
523
|
// the whole content of the declaration.
|
|
466
524
|
{
|
|
467
|
-
name: "onsetDurationFormula",
|
|
525
|
+
name: "data.onsetDurationFormula",
|
|
526
|
+
legacyKey: "onsetDurationFormula",
|
|
468
527
|
to: "onsetDurationFormula",
|
|
469
528
|
...DURATION_FORMULA,
|
|
470
529
|
omitWhenAbsent: true,
|
|
@@ -472,7 +531,8 @@ export const ITEM_FIELDS = Object.freeze({
|
|
|
472
531
|
"Interval from contracting the affliction to the start of onset. Omitted when unset, leaving no incubation.",
|
|
473
532
|
},
|
|
474
533
|
{
|
|
475
|
-
name: "onsetDurationBase",
|
|
534
|
+
name: "data.onsetDurationBase",
|
|
535
|
+
legacyKey: "onsetDurationBase",
|
|
476
536
|
to: "onsetDurationBase",
|
|
477
537
|
...DURATION_BASE,
|
|
478
538
|
omitWhenAbsent: true,
|
|
@@ -480,7 +540,8 @@ export const ITEM_FIELDS = Object.freeze({
|
|
|
480
540
|
"The onset interval in seconds, standing in for a roll of the formula. Omitted when unset.",
|
|
481
541
|
},
|
|
482
542
|
{
|
|
483
|
-
name: "healingCheckDurationFormula",
|
|
543
|
+
name: "data.healingCheckDurationFormula",
|
|
544
|
+
legacyKey: "healingCheckDurationFormula",
|
|
484
545
|
to: "healingCheckDurationFormula",
|
|
485
546
|
...DURATION_FORMULA,
|
|
486
547
|
omitWhenAbsent: true,
|
|
@@ -488,7 +549,8 @@ export const ITEM_FIELDS = Object.freeze({
|
|
|
488
549
|
"Interval between healing checks, once the affliction is symptomatic. Omitted when unset.",
|
|
489
550
|
},
|
|
490
551
|
{
|
|
491
|
-
name: "healingCheckDurationBase",
|
|
552
|
+
name: "data.healingCheckDurationBase",
|
|
553
|
+
legacyKey: "healingCheckDurationBase",
|
|
492
554
|
to: "healingCheckDurationBase",
|
|
493
555
|
...DURATION_BASE,
|
|
494
556
|
omitWhenAbsent: true,
|
|
@@ -496,7 +558,8 @@ export const ITEM_FIELDS = Object.freeze({
|
|
|
496
558
|
"The healing-check interval in seconds, standing in for a roll of the formula. Omitted when unset.",
|
|
497
559
|
},
|
|
498
560
|
{
|
|
499
|
-
name: "resolutionDurationFormula",
|
|
561
|
+
name: "data.resolutionDurationFormula",
|
|
562
|
+
legacyKey: "resolutionDurationFormula",
|
|
500
563
|
to: "resolutionDurationFormula",
|
|
501
564
|
...DURATION_FORMULA,
|
|
502
565
|
omitWhenAbsent: true,
|
|
@@ -504,7 +567,8 @@ export const ITEM_FIELDS = Object.freeze({
|
|
|
504
567
|
"Interval from onset to the affliction running its course. Omitted when unset.",
|
|
505
568
|
},
|
|
506
569
|
{
|
|
507
|
-
name: "resolutionDurationBase",
|
|
570
|
+
name: "data.resolutionDurationBase",
|
|
571
|
+
legacyKey: "resolutionDurationBase",
|
|
508
572
|
to: "resolutionDurationBase",
|
|
509
573
|
...DURATION_BASE,
|
|
510
574
|
omitWhenAbsent: true,
|
|
@@ -711,7 +775,7 @@ export const ITEM_FIELDS = Object.freeze({
|
|
|
711
775
|
{
|
|
712
776
|
name: "assocSkillCode",
|
|
713
777
|
to: "assocSkillCode",
|
|
714
|
-
|
|
778
|
+
code: "skill",
|
|
715
779
|
...BLANK_IS_NULL,
|
|
716
780
|
default: null,
|
|
717
781
|
describe: "Shortcode of the skill the mystery is tested against.",
|
|
@@ -719,7 +783,7 @@ export const ITEM_FIELDS = Object.freeze({
|
|
|
719
783
|
{
|
|
720
784
|
name: "assocAffiliationCode",
|
|
721
785
|
to: "assocAffiliationCode",
|
|
722
|
-
|
|
786
|
+
code: "affiliation",
|
|
723
787
|
...BLANK_IS_NULL,
|
|
724
788
|
default: null,
|
|
725
789
|
describe:
|
|
@@ -733,14 +797,16 @@ export const ITEM_FIELDS = Object.freeze({
|
|
|
733
797
|
describe: "The mystery's level before any modifier.",
|
|
734
798
|
},
|
|
735
799
|
{
|
|
736
|
-
name: "skillAptitudes",
|
|
800
|
+
name: "data.skillAptitudes",
|
|
801
|
+
legacyKey: "skillAptitudes",
|
|
737
802
|
to: "skillAptitudes",
|
|
738
803
|
...SKILL_APTITUDES,
|
|
739
804
|
default: {},
|
|
740
805
|
describe: "Aptitude the mystery grants, per skill selector.",
|
|
741
806
|
},
|
|
742
807
|
{
|
|
743
|
-
name: "charges",
|
|
808
|
+
name: "data.charges",
|
|
809
|
+
legacyKey: "charges",
|
|
744
810
|
to: "charges",
|
|
745
811
|
...CHARGES,
|
|
746
812
|
default: { value: null, max: null },
|
|
@@ -760,7 +826,7 @@ export const ITEM_FIELDS = Object.freeze({
|
|
|
760
826
|
{
|
|
761
827
|
name: "assocSkillCode",
|
|
762
828
|
to: "assocSkillCode",
|
|
763
|
-
|
|
829
|
+
code: "skill",
|
|
764
830
|
...AS_AUTHORED,
|
|
765
831
|
default: "",
|
|
766
832
|
describe: "Shortcode of the skill the ability is tested against.",
|
|
@@ -768,7 +834,7 @@ export const ITEM_FIELDS = Object.freeze({
|
|
|
768
834
|
{
|
|
769
835
|
name: "assocAffiliationCode",
|
|
770
836
|
to: "assocAffiliationCode",
|
|
771
|
-
|
|
837
|
+
code: "affiliation",
|
|
772
838
|
...BLANK_IS_NULL,
|
|
773
839
|
default: null,
|
|
774
840
|
describe:
|
|
@@ -796,7 +862,8 @@ export const ITEM_FIELDS = Object.freeze({
|
|
|
796
862
|
describe: "The ability's level before any modifier.",
|
|
797
863
|
},
|
|
798
864
|
{
|
|
799
|
-
name: "charges",
|
|
865
|
+
name: "data.charges",
|
|
866
|
+
legacyKey: "charges",
|
|
800
867
|
to: "charges",
|
|
801
868
|
...CHARGES,
|
|
802
869
|
default: { value: null, max: null },
|
|
@@ -884,7 +951,7 @@ export const ITEM_FIELDS = Object.freeze({
|
|
|
884
951
|
{
|
|
885
952
|
name: "parentSkillCode",
|
|
886
953
|
to: "parentSkillCode",
|
|
887
|
-
|
|
954
|
+
code: "skill",
|
|
888
955
|
...AS_AUTHORED,
|
|
889
956
|
default: "",
|
|
890
957
|
describe: "Shortcode of the skill this one specialises, for a specialisation.",
|
|
@@ -959,7 +1026,8 @@ export const ITEM_FIELDS = Object.freeze({
|
|
|
959
1026
|
// `bloodLossAdvance*` is the one an author reaches for most: a trauma
|
|
960
1027
|
// that sets it bleeds, and one that leaves it unset does not.
|
|
961
1028
|
{
|
|
962
|
-
name: "healingCheckDurationFormula",
|
|
1029
|
+
name: "data.healingCheckDurationFormula",
|
|
1030
|
+
legacyKey: "healingCheckDurationFormula",
|
|
963
1031
|
to: "healingCheckDurationFormula",
|
|
964
1032
|
...DURATION_FORMULA,
|
|
965
1033
|
omitWhenAbsent: true,
|
|
@@ -967,7 +1035,8 @@ export const ITEM_FIELDS = Object.freeze({
|
|
|
967
1035
|
"Interval between healing checks. Omitted when unset, leaving the world's configured interval to apply.",
|
|
968
1036
|
},
|
|
969
1037
|
{
|
|
970
|
-
name: "healingCheckDurationBase",
|
|
1038
|
+
name: "data.healingCheckDurationBase",
|
|
1039
|
+
legacyKey: "healingCheckDurationBase",
|
|
971
1040
|
to: "healingCheckDurationBase",
|
|
972
1041
|
...DURATION_BASE,
|
|
973
1042
|
omitWhenAbsent: true,
|
|
@@ -975,7 +1044,8 @@ export const ITEM_FIELDS = Object.freeze({
|
|
|
975
1044
|
"The healing-check interval in seconds, standing in for a roll of the formula. Omitted when unset.",
|
|
976
1045
|
},
|
|
977
1046
|
{
|
|
978
|
-
name: "bloodLossAdvanceDurationFormula",
|
|
1047
|
+
name: "data.bloodLossAdvanceDurationFormula",
|
|
1048
|
+
legacyKey: "bloodLossAdvanceDurationFormula",
|
|
979
1049
|
to: "bloodLossAdvanceDurationFormula",
|
|
980
1050
|
...DURATION_FORMULA,
|
|
981
1051
|
omitWhenAbsent: true,
|
|
@@ -983,7 +1053,8 @@ export const ITEM_FIELDS = Object.freeze({
|
|
|
983
1053
|
"Interval between blood-loss advances. Omitted when unset, leaving the world's configured interval to apply.",
|
|
984
1054
|
},
|
|
985
1055
|
{
|
|
986
|
-
name: "bloodLossAdvanceDurationBase",
|
|
1056
|
+
name: "data.bloodLossAdvanceDurationBase",
|
|
1057
|
+
legacyKey: "bloodLossAdvanceDurationBase",
|
|
987
1058
|
to: "bloodLossAdvanceDurationBase",
|
|
988
1059
|
...DURATION_BASE,
|
|
989
1060
|
omitWhenAbsent: true,
|
|
@@ -991,7 +1062,8 @@ export const ITEM_FIELDS = Object.freeze({
|
|
|
991
1062
|
"The blood-loss interval in seconds. Setting it is what makes the wound bleed; omitted when unset, and the wound does not.",
|
|
992
1063
|
},
|
|
993
1064
|
{
|
|
994
|
-
name: "courseDurationFormula",
|
|
1065
|
+
name: "data.courseDurationFormula",
|
|
1066
|
+
legacyKey: "courseDurationFormula",
|
|
995
1067
|
to: "courseDurationFormula",
|
|
996
1068
|
...DURATION_FORMULA,
|
|
997
1069
|
omitWhenAbsent: true,
|
|
@@ -999,7 +1071,8 @@ export const ITEM_FIELDS = Object.freeze({
|
|
|
999
1071
|
"Interval between course tests, for a condition that runs one — shock, coma, infection. Omitted when unset.",
|
|
1000
1072
|
},
|
|
1001
1073
|
{
|
|
1002
|
-
name: "courseDurationBase",
|
|
1074
|
+
name: "data.courseDurationBase",
|
|
1075
|
+
legacyKey: "courseDurationBase",
|
|
1003
1076
|
to: "courseDurationBase",
|
|
1004
1077
|
...DURATION_BASE,
|
|
1005
1078
|
omitWhenAbsent: true,
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* An Address position, as a field declaration states it.
|
|
3
|
+
*
|
|
4
|
+
* @typedef {object} AddressPosition
|
|
5
|
+
* @property {string} type - The type an omitted `<type>` segment takes.
|
|
6
|
+
* @property {readonly string[]} accepts - Every type the position accepts.
|
|
7
|
+
* @property {"value"|"items"|"keys"} [holds] - Where the Addresses are.
|
|
8
|
+
* Defaults to `value`.
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* What a reduction could not do, for a caller to report.
|
|
12
|
+
*
|
|
13
|
+
* @typedef {object} AddressFinding
|
|
14
|
+
* @property {string} key - The field, named as an author writes it.
|
|
15
|
+
* @property {string} written - The authored value, so the caller can locate the
|
|
16
|
+
* finding at the line carrying it rather than at the key.
|
|
17
|
+
* @property {string} message - One sentence, naming the fix.
|
|
18
|
+
*/
|
|
19
|
+
/**
|
|
20
|
+
* The declarations that state an Address position.
|
|
21
|
+
*
|
|
22
|
+
* @param {readonly object[]} fields - A field declaration.
|
|
23
|
+
* @returns {object[]} Only the fields carrying an `address` statement.
|
|
24
|
+
*/
|
|
25
|
+
export function addressFields(fields: readonly object[]): object[];
|
|
26
|
+
/**
|
|
27
|
+
* Reduce every Address a compiled block holds to the Shortcode it names.
|
|
28
|
+
*
|
|
29
|
+
* The block is edited in place, as {@link
|
|
30
|
+
* module:engine/system-block.mergeSystemData} edits it: what the caller holds is
|
|
31
|
+
* the document being assembled, and a field the reduction cannot read is left
|
|
32
|
+
* exactly as authored — the findings stop the build, so nothing ships either
|
|
33
|
+
* way, and an untouched value is what a reader of the failing note sees.
|
|
34
|
+
*
|
|
35
|
+
* @param {object} emitted - The `system` block, already built.
|
|
36
|
+
* @param {readonly object[]} fields - The type's field declaration.
|
|
37
|
+
* @param {import("./address.mjs").AddressVocabulary & {package?: string}}
|
|
38
|
+
* vocabulary - The tree's vocabularies and the package the values are written
|
|
39
|
+
* in.
|
|
40
|
+
* @returns {AddressFinding[]} Every value that could not be reduced.
|
|
41
|
+
*/
|
|
42
|
+
export function reduceAddressFields(emitted: object, fields: readonly object[], vocabulary?: import("./address.mjs").AddressVocabulary & {
|
|
43
|
+
package?: string;
|
|
44
|
+
}): AddressFinding[];
|
|
45
|
+
/**
|
|
46
|
+
* How many values a position holds.
|
|
47
|
+
*
|
|
48
|
+
* - `value` — the field's value is one Address.
|
|
49
|
+
* - `items` — every element of a list is one.
|
|
50
|
+
* - `keys` — every **key** of a map is one, and the values are untouched.
|
|
51
|
+
*
|
|
52
|
+
* @type {readonly string[]}
|
|
53
|
+
*/
|
|
54
|
+
export const ADDRESS_FIELD_SHAPES: readonly string[];
|
|
55
|
+
/**
|
|
56
|
+
* An Address position, as a field declaration states it.
|
|
57
|
+
*/
|
|
58
|
+
export type AddressPosition = {
|
|
59
|
+
/**
|
|
60
|
+
* - The type an omitted `<type>` segment takes.
|
|
61
|
+
*/
|
|
62
|
+
type: string;
|
|
63
|
+
/**
|
|
64
|
+
* - Every type the position accepts.
|
|
65
|
+
*/
|
|
66
|
+
accepts: readonly string[];
|
|
67
|
+
/**
|
|
68
|
+
* - Where the Addresses are.
|
|
69
|
+
* Defaults to `value`.
|
|
70
|
+
*/
|
|
71
|
+
holds?: "keys" | "value" | "items" | undefined;
|
|
72
|
+
};
|
|
73
|
+
/**
|
|
74
|
+
* What a reduction could not do, for a caller to report.
|
|
75
|
+
*/
|
|
76
|
+
export type AddressFinding = {
|
|
77
|
+
/**
|
|
78
|
+
* - The field, named as an author writes it.
|
|
79
|
+
*/
|
|
80
|
+
key: string;
|
|
81
|
+
/**
|
|
82
|
+
* - The authored value, so the caller can locate the
|
|
83
|
+
* finding at the line carrying it rather than at the key.
|
|
84
|
+
*/
|
|
85
|
+
written: string;
|
|
86
|
+
/**
|
|
87
|
+
* - One sentence, naming the fix.
|
|
88
|
+
*/
|
|
89
|
+
message: string;
|
|
90
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Render typed properties at a generated-output boundary.
|
|
3
|
+
* @param {any} value - A tuple-bearing tree.
|
|
4
|
+
* @param {WeakMap<object, object>} [seen] - Shared containers in this output.
|
|
5
|
+
* @returns {any} A serializable tree containing full Addresses.
|
|
6
|
+
*/
|
|
7
|
+
export function encodeAddresses(value: any, seen?: WeakMap<object, object>): any;
|
|
8
|
+
/**
|
|
9
|
+
* Clone mutable note state while retaining immutable Address identities.
|
|
10
|
+
* @param {any} value - Typed note state.
|
|
11
|
+
* @returns {any} An independent mutable container tree.
|
|
12
|
+
*/
|
|
13
|
+
export function cloneAddressState(value: any): any;
|
|
14
|
+
/** Address-keyed properties hold typed entries rather than string object keys. */
|
|
15
|
+
export class AddressEntries {
|
|
16
|
+
/** @param {Array<{target: object, value: unknown, sourceKey: string}>} entries - Typed entries and diagnostic source keys. */
|
|
17
|
+
constructor(entries: Array<{
|
|
18
|
+
target: object;
|
|
19
|
+
value: unknown;
|
|
20
|
+
sourceKey: string;
|
|
21
|
+
}>);
|
|
22
|
+
entries: {
|
|
23
|
+
target: object;
|
|
24
|
+
value: unknown;
|
|
25
|
+
sourceKey: string;
|
|
26
|
+
}[];
|
|
27
|
+
}
|
|
28
|
+
/** An Address and the section within its document. */
|
|
29
|
+
export class AddressLink {
|
|
30
|
+
/** @param {object} target - Complete tuple. @param {string} anchor - Section slug. */
|
|
31
|
+
constructor(target: object, anchor: string);
|
|
32
|
+
target: object;
|
|
33
|
+
anchor: string;
|
|
34
|
+
}
|