@archivist-gg/dnd5e 0.3.0 → 0.3.4
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/LICENSES/SRD.md +25 -6
- package/dist/armor/armor.codec.js +4 -3
- package/dist/armor/armor.parser.js +3 -2
- package/dist/armor/armor.schema.d.ts +4 -0
- package/dist/armor/armor.schema.js +2 -1
- package/dist/armor/armor.types.d.ts +8 -0
- package/dist/background/background.codec.js +7 -6
- package/dist/background/background.parser.js +6 -5
- package/dist/background/background.schema.d.ts +34 -0
- package/dist/background/background.schema.js +9 -6
- package/dist/background/background.types.d.ts +22 -0
- package/dist/{chunk-4TIJKN6O.js → chunk-23LZLBJK.js} +1 -1
- package/dist/{chunk-AFKTJXRA.js → chunk-2DFENQIJ.js} +18 -0
- package/dist/chunk-2FRUSVZS.js +489 -0
- package/dist/chunk-4FWNK4FD.js +159 -0
- package/dist/chunk-4U55VNC7.js +22 -0
- package/dist/{chunk-4JHOHWBI.js → chunk-4XTNPNQB.js} +1 -1
- package/dist/{chunk-HCP3GMHS.js → chunk-5N2GW72F.js} +15 -2
- package/dist/{chunk-42Y5IJKT.js → chunk-5U5FFFA3.js} +5 -1
- package/dist/{chunk-4F6AIZ36.js → chunk-5XMQPTHD.js} +1 -1
- package/dist/{chunk-GJOI2GHP.js → chunk-6GNXYAYP.js} +1 -1
- package/dist/chunk-6PKV5V2H.js +178 -0
- package/dist/{chunk-66XXW2Z2.js → chunk-6PXTNCBP.js} +2 -2
- package/dist/chunk-6X2NV665.js +33 -0
- package/dist/{chunk-LV4SNWZQ.js → chunk-6X4KUDMU.js} +8 -1
- package/dist/{chunk-ZMR77DDL.js → chunk-AW3EHF3L.js} +1 -1
- package/dist/chunk-CJYCVNW2.js +7 -0
- package/dist/chunk-COEOOQX2.js +133 -0
- package/dist/{chunk-XTIQWSFM.js → chunk-D5U7GMPX.js} +1 -1
- package/dist/{chunk-RAWJTA45.js → chunk-DEEHHLAP.js} +1 -1
- package/dist/chunk-DPUJDOKV.js +365 -0
- package/dist/{chunk-73HOFQQ5.js → chunk-ESS46GR4.js} +1 -1
- package/dist/chunk-EVMUJYUD.js +195 -0
- package/dist/{chunk-2BWAID3Y.js → chunk-FDBWYMZK.js} +29 -3
- package/dist/{chunk-K6Q5OUGK.js → chunk-GFZ7PITJ.js} +86 -10
- package/dist/chunk-H7KBLR4X.js +81 -0
- package/dist/{chunk-L7E2UT5A.js → chunk-HB7XZXDK.js} +5 -1
- package/dist/{chunk-VTYUBINW.js → chunk-HJ5EEZ47.js} +1 -1
- package/dist/{chunk-6NK2MUD3.js → chunk-HZA7OE7N.js} +9 -2
- package/dist/{chunk-A4WENOUQ.js → chunk-I2NDWFDD.js} +52 -8
- package/dist/{chunk-RSDRMH54.js → chunk-IMZFOOVL.js} +1 -1
- package/dist/{chunk-3DZ74AKK.js → chunk-IN4M4X7P.js} +8 -2
- package/dist/chunk-IUAAXXNO.js +58 -0
- package/dist/{chunk-XJNECUPT.js → chunk-JC5UNIVM.js} +19 -0
- package/dist/chunk-JJ46T5XX.js +297 -0
- package/dist/{chunk-TUIFSVLI.js → chunk-JRDPUDT5.js} +30 -3
- package/dist/{chunk-24GFQU7T.js → chunk-JSZ4H6AQ.js} +1 -1
- package/dist/chunk-KU3YLF6D.js +106 -0
- package/dist/{chunk-5INR4NSL.js → chunk-LDDCNPHD.js} +1 -1
- package/dist/{chunk-DZXSWSBP.js → chunk-LMBAEIP6.js} +1 -1
- package/dist/chunk-LVQLWRCU.js +15 -0
- package/dist/chunk-MI7P3NX3.js +161 -0
- package/dist/chunk-O4SRD3J5.js +165 -0
- package/dist/{chunk-EMOORSQ7.js → chunk-OSQFPGLM.js} +45 -6
- package/dist/chunk-OZP6JFGT.js +162 -0
- package/dist/{chunk-NAEPSZAM.js → chunk-PDJSUH24.js} +24 -2
- package/dist/chunk-PP2UHLBA.js +50 -0
- package/dist/chunk-PVCEA4HZ.js +6 -0
- package/dist/{chunk-XLSVNUTK.js → chunk-R3VAKWKW.js} +1 -1
- package/dist/chunk-RIXI5D3R.js +89 -0
- package/dist/chunk-RLGQ5PZZ.js +16 -0
- package/dist/chunk-S7REMWW4.js +21 -0
- package/dist/{chunk-7VJ6BOA5.js → chunk-SMLXZUBH.js} +9 -1
- package/dist/{chunk-NXSWH3AE.js → chunk-T26ZVCL5.js} +1 -1
- package/dist/chunk-TOM66P2P.js +38 -0
- package/dist/chunk-UA5KS2PL.js +26 -0
- package/dist/{chunk-N6N74K6X.js → chunk-UBBKSYBY.js} +1 -1
- package/dist/{chunk-353WXS6S.js → chunk-UIRMA5KM.js} +1 -1
- package/dist/{chunk-GE4TLPWM.js → chunk-US5IKYCW.js} +1 -1
- package/dist/chunk-UXPGW4TI.js +101 -0
- package/dist/chunk-VQAXTIBW.js +100 -0
- package/dist/{chunk-WP2CX2JO.js → chunk-WELIKLZF.js} +22 -1
- package/dist/chunk-WPWOHGPI.js +172 -0
- package/dist/{chunk-GZ46OVGZ.js → chunk-WSVMLNTO.js} +1 -1
- package/dist/{chunk-4LZJXJJS.js → chunk-WXWPK3LI.js} +6 -2
- package/dist/{chunk-ZZGEVJKX.js → chunk-XBQMCEI2.js} +1 -1
- package/dist/{chunk-PHQRGDRQ.js → chunk-XGOFP7AQ.js} +5 -1
- package/dist/chunk-XJ2F2WO6.js +8 -0
- package/dist/chunk-XQCSGNXE.js +1580 -0
- package/dist/chunk-YBLDE5CG.js +42 -0
- package/dist/{chunk-JEYQU3JT.js → chunk-YHYTW5QA.js} +2 -18
- package/dist/{chunk-TLYDBT5F.js → chunk-YJJTISBN.js} +64 -7
- package/dist/{chunk-PZOWBI3B.js → chunk-YLL2QXY2.js} +7 -2
- package/dist/{chunk-MDEJHMKK.js → chunk-ZONJ66NE.js} +26 -5
- package/dist/class/class.codec.js +12 -9
- package/dist/class/class.parser.js +11 -8
- package/dist/class/class.schema.d.ts +55 -3
- package/dist/class/class.schema.js +9 -7
- package/dist/class/class.types.d.ts +48 -3
- package/dist/condition/condition.codec.d.ts +9 -0
- package/dist/condition/condition.entity-type.d.ts +2 -0
- package/dist/condition/condition.parser.d.ts +13 -0
- package/dist/condition/condition.parser.js +7 -0
- package/dist/condition/condition.schema.d.ts +29 -0
- package/dist/condition/condition.types.d.ts +15 -0
- package/dist/condition/condition.types.js +0 -0
- package/dist/dnd/constants.d.ts +22 -0
- package/dist/dnd/constants.js +9 -3
- package/dist/dnd/formula-tags.js +2 -2
- package/dist/dnd/math.d.ts +26 -0
- package/dist/dnd/math.js +12 -2
- package/dist/dnd/prose-tags.js +1 -1
- package/dist/dnd/resource-formula.d.ts +36 -10
- package/dist/dnd/resource-formula.js +10 -155
- package/dist/dnd/srd-tag-converter.js +3 -3
- package/dist/dnd/tag-grammar.js +1 -1
- package/dist/dnd/warn-once.d.ts +2 -0
- package/dist/dnd/warn-once.js +8 -0
- package/dist/entities/base-item-resolver.js +2 -2
- package/dist/entities/slug.d.ts +13 -0
- package/dist/entities/slug.js +5 -3
- package/dist/entities/wikilink-display.d.ts +3 -0
- package/dist/entities/wikilink-display.js +10 -0
- package/dist/feat/feat.category-codes.d.ts +32 -0
- package/dist/feat/feat.category-codes.js +14 -0
- package/dist/feat/feat.codec.js +7 -5
- package/dist/feat/feat.parser.js +6 -4
- package/dist/feat/feat.schema.d.ts +230 -0
- package/dist/feat/feat.schema.js +5 -3
- package/dist/feat/feat.types.d.ts +37 -1
- package/dist/index.js +2120 -6923
- package/dist/item/item.ai-schema.d.ts +1 -1
- package/dist/item/item.codec.js +4 -3
- package/dist/item/item.enrichment.js +4 -4
- package/dist/item/item.parser.js +3 -2
- package/dist/item/item.schema.d.ts +69 -3
- package/dist/item/item.schema.js +2 -1
- package/dist/item/item.types.d.ts +69 -3
- package/dist/monster/monster.codec.d.ts +7 -6
- package/dist/monster/monster.enrichment.js +4 -4
- package/dist/monster/monster.format.d.ts +135 -0
- package/dist/monster/monster.format.js +78 -0
- package/dist/monster/monster.parser.d.ts +6 -1
- package/dist/monster/monster.parser.js +10 -1
- package/dist/monster/monster.schema.d.ts +369 -0
- package/dist/monster/monster.schema.js +34 -0
- package/dist/monster/monster.types.d.ts +200 -14
- package/dist/optional-feature/optional-feature.codec.js +6 -5
- package/dist/optional-feature/optional-feature.parser.js +5 -4
- package/dist/optional-feature/optional-feature.schema.d.ts +176 -0
- package/dist/optional-feature/optional-feature.schema.js +4 -3
- package/dist/pack.d.ts +1 -1
- package/dist/pc/conditions.constants.d.ts +0 -1
- package/dist/pc/conditions.constants.js +1 -3
- package/dist/pc/decision-recognizer.js +1 -1
- package/dist/pc/pc.additional-spells.d.ts +47 -0
- package/dist/pc/pc.additional-spells.js +23 -0
- package/dist/pc/pc.asi-flatten.d.ts +18 -0
- package/dist/pc/pc.decision-engine.d.ts +106 -5
- package/dist/pc/pc.decision-engine.js +28 -10
- package/dist/pc/pc.defense-normalize.d.ts +11 -0
- package/dist/pc/pc.defense-normalize.js +6 -0
- package/dist/pc/pc.equipment.d.ts +30 -1
- package/dist/pc/pc.equipment.js +12 -7
- package/dist/pc/pc.feature-effects.d.ts +225 -11
- package/dist/pc/pc.feature-effects.js +21 -5
- package/dist/pc/pc.parser.js +2 -2
- package/dist/pc/pc.pools.d.ts +11 -3
- package/dist/pc/pc.pools.js +9 -13
- package/dist/pc/pc.proficiencies.d.ts +60 -4
- package/dist/pc/pc.proficiencies.js +89 -37
- package/dist/pc/pc.proficiency-grants.d.ts +58 -0
- package/dist/pc/pc.proficiency-normalize.d.ts +29 -0
- package/dist/pc/pc.proficiency-normalize.js +12 -0
- package/dist/pc/pc.proficiency-query.d.ts +13 -0
- package/dist/pc/pc.proficiency-query.js +5 -1
- package/dist/pc/pc.recalc.d.ts +69 -14
- package/dist/pc/pc.recalc.js +291 -142
- package/dist/pc/pc.resolver.d.ts +34 -8
- package/dist/pc/pc.resolver.js +27 -12
- package/dist/pc/pc.resource-seed.d.ts +3 -2
- package/dist/pc/pc.resource-seed.js +19 -17
- package/dist/pc/pc.resources.d.ts +87 -0
- package/dist/pc/pc.resources.js +21 -0
- package/dist/pc/pc.rest.d.ts +10 -1
- package/dist/pc/pc.rest.js +66 -12
- package/dist/pc/pc.schema.d.ts +147 -7
- package/dist/pc/pc.schema.js +4 -2
- package/dist/pc/pc.slotting.js +3 -3
- package/dist/pc/pc.spellcasting.d.ts +80 -7
- package/dist/pc/pc.spellcasting.js +18 -6
- package/dist/pc/pc.table-column.d.ts +23 -0
- package/dist/pc/pc.table-column.js +13 -3
- package/dist/pc/pc.types.d.ts +253 -16
- package/dist/pc/pool-layout.d.ts +47 -0
- package/dist/pc/pool-layout.js +16 -0
- package/dist/pc/roll-scope.d.ts +2 -0
- package/dist/pc/roll-scope.js +8 -0
- package/dist/pc/roll-tag-labels.d.ts +40 -0
- package/dist/pc/roll-tag-labels.js +17 -0
- package/dist/pc/spell-source.d.ts +21 -0
- package/dist/pc/spell-source.js +13 -0
- package/dist/race/race.codec.js +9 -7
- package/dist/race/race.parser.js +8 -6
- package/dist/race/race.schema.d.ts +51 -1
- package/dist/race/race.schema.js +8 -5
- package/dist/race/race.structural.d.ts +7 -0
- package/dist/race/race.structural.js +6 -0
- package/dist/race/race.types.d.ts +20 -0
- package/dist/schemas/attack-schema.d.ts +5 -0
- package/dist/schemas/caster-type-schema.d.ts +14 -0
- package/dist/schemas/caster-type-schema.js +6 -0
- package/dist/schemas/choice-schema.js +2 -2
- package/dist/schemas/entity-extras-schema.d.ts +53 -0
- package/dist/schemas/entity-extras-schema.js +10 -0
- package/dist/schemas/equipment-grant-schema.d.ts +2 -0
- package/dist/schemas/equipment-grant-schema.js +1 -1
- package/dist/schemas/feature-alias.d.ts +34 -0
- package/dist/schemas/feature-effect-schema.d.ts +124 -0
- package/dist/schemas/feature-effect-schema.js +1 -1
- package/dist/schemas/feature-schema.d.ts +8 -0
- package/dist/schemas/feature-schema.js +6 -4
- package/dist/schemas/resource-schema.d.ts +43 -0
- package/dist/schemas/resource-schema.js +1 -1
- package/dist/schemas/selection-pool-schema.d.ts +2 -0
- package/dist/schemas/selection-pool-schema.js +1 -1
- package/dist/spell/spell.access.js +23 -3
- package/dist/spell/spell.codec.js +4 -3
- package/dist/spell/spell.enrichment.js +4 -4
- package/dist/spell/spell.parser.d.ts +30 -0
- package/dist/spell/spell.parser.js +9 -2
- package/dist/spell/spell.scaling.d.ts +27 -6
- package/dist/spell/spell.scaling.js +25 -6
- package/dist/spell/spell.schema.d.ts +44 -2
- package/dist/spell/spell.schema.js +2 -1
- package/dist/spell/spell.types.d.ts +14 -0
- package/dist/subclass/subclass.codec.d.ts +1 -1
- package/dist/subclass/subclass.codec.js +11 -8
- package/dist/subclass/subclass.parser.js +10 -7
- package/dist/subclass/subclass.schema.d.ts +54 -7
- package/dist/subclass/subclass.schema.js +8 -6
- package/dist/subclass/subclass.types.d.ts +20 -2
- package/dist/types/choice.d.ts +56 -0
- package/dist/types/choice.js +21 -3
- package/dist/types/equipment-grant.d.ts +8 -1
- package/dist/types/feature-effect.d.ts +78 -23
- package/dist/types/feature.d.ts +70 -1
- package/dist/types/optional-feature.types.d.ts +28 -0
- package/dist/types/resource.d.ts +21 -1
- package/dist/types/selection-pool.d.ts +17 -2
- package/dist/weapon/weapon.classify.js +2 -2
- package/dist/weapon/weapon.codec.js +4 -3
- package/dist/weapon/weapon.parser.js +3 -2
- package/dist/weapon/weapon.schema.d.ts +4 -0
- package/dist/weapon/weapon.schema.js +2 -1
- package/dist/weapon/weapon.types.d.ts +8 -0
- package/package.json +2 -2
- package/dist/chunk-5MZSB6OM.js +0 -1089
- package/dist/chunk-5XUXXAQJ.js +0 -30
- package/dist/chunk-7P65Q426.js +0 -158
- package/dist/chunk-AIRFC5NQ.js +0 -143
- package/dist/chunk-BH6AMZVY.js +0 -25
- package/dist/chunk-CZPMTQOY.js +0 -68
- package/dist/chunk-M2EMFD6S.js +0 -269
- package/dist/chunk-N2JE7BWL.js +0 -81
- package/dist/chunk-NXR3BD2V.js +0 -90
- package/dist/chunk-Q5K6LWBZ.js +0 -45
- package/dist/chunk-TZK36BU7.js +0 -38
- package/dist/chunk-W7HWMMBF.js +0 -46
- package/dist/chunk-Y4I74YEG.js +0 -33
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { EntryAffordance, PoolLayout } from "../types/selection-pool.js";
|
|
2
|
+
import type { ResolvedPoolEntry } from "./pc.types.js";
|
|
3
|
+
/** The ONE `rendering_hint` → `PoolLayout` table (R4-G4 §4.2.2, invariant 3): a DATA table in the
|
|
4
|
+
* RESET_LABELS shape. Absent keys route to the default, and R4-G5 added NONE: `pool-selection` and
|
|
5
|
+
* `stance` are a measured empty delta (spec §10) and `granted-die-to-ally` became a per-ROW affordance
|
|
6
|
+
* in the table below, so this one still holds exactly the two G4 keys. */
|
|
7
|
+
export declare const RENDERING_HINT_LAYOUT: Readonly<Record<string, PoolLayout>>;
|
|
8
|
+
/** The majority mapped hint over the pool's members; members with an empty or unmapped hint do not
|
|
9
|
+
* vote; no votes → undefined; a tie between two mapped values → undefined (Gate 0 Q8).
|
|
10
|
+
* UNMAPPED is decided by OWN-property lookup, never by truthiness of a plain index (review M-2):
|
|
11
|
+
* `rendering_hint` is a free `z.string().optional()` on converter data, so a member may carry any
|
|
12
|
+
* string, and an object-literal table answers the `Object.prototype` keys through the prototype
|
|
13
|
+
* chain. Measured 2026-09-06 on this table: `constructor`, `toString`, `hasOwnProperty` and
|
|
14
|
+
* `valueOf` each index to a FUNCTION and each has `hasOwnProperty` false, while the two mapped
|
|
15
|
+
* hints, `dice-pool` and `point-pool`, are the only keys that are both a string and own (review
|
|
16
|
+
* M-1: the earlier wording named `dice-pool` alone). Without the guard a lone junk hint voted that
|
|
17
|
+
* function as the layout, and one junk member beside genuine `dice-pool` members collapsed a
|
|
18
|
+
* correct majority into a phantom tie. */
|
|
19
|
+
export declare function derivePoolLayout(entries: ReadonlyArray<ResolvedPoolEntry>): PoolLayout | undefined;
|
|
20
|
+
/** The ONE `rendering_hint` to `EntryAffordance` table (R4-G5 §4.2.1, invariant 3): the PER-ENTRY sibling of
|
|
21
|
+
* `RENDERING_HINT_LAYOUT`. `granted-die-to-ally` is its only key, and the four documents carrying it
|
|
22
|
+
* (Commander's Strike x2, Rally x2) are field-identical to the other 39 maneuvers except that hint, so a
|
|
23
|
+
* per-row affordance is the only place their meaning can land. `stance` gets NO key (its three hinted documents
|
|
24
|
+
* are field-identical to three unhinted siblings: a measured empty delta) and `pool-selection` none. */
|
|
25
|
+
export declare const RENDERING_HINT_AFFORDANCE: Readonly<Record<string, EntryAffordance>>;
|
|
26
|
+
/** The entry's affordance, by OWN-property lookup (`derivePoolLayout`'s precedent, invariant 3): `rendering_hint`
|
|
27
|
+
* is a free `z.string().optional()` on converter data, so a member may carry ANY string, and an object-literal
|
|
28
|
+
* table answers `constructor` / `toString` / `hasOwnProperty` / `valueOf` through the prototype chain with a
|
|
29
|
+
* FUNCTION. Absent, empty and unmapped hints all return undefined. */
|
|
30
|
+
export declare function deriveEntryAffordance(entity: ResolvedPoolEntry["entity"]): EntryAffordance | undefined;
|
|
31
|
+
/** Caption TEMPLATES per affordance, in the `RESET_LABELS` shape: the game sentence lives in DATA here, never in
|
|
32
|
+
* a renderer (invariant 3). `{amount}` and `{die}` are filled by `formatAffordanceCaption`.
|
|
33
|
+
*
|
|
34
|
+
* The two placeholders ABUT (R4 {G5, G6} live rider N-1-12): the sheet read `1 d8 to an ally`, which is not how
|
|
35
|
+
* a die is written. `{die}` is a FACE by contract · the caller passes what `resolveScalingDie` returns, which is
|
|
36
|
+
* `base` or one of `scaling`'s entries, and every one of those in shipped data is face-shaped ("d6" throughout
|
|
37
|
+
* the SRD runtime JSON and the compendium bundle) · so amount and face compose into one dice expression. */
|
|
38
|
+
export declare const AFFORDANCE_CAPTIONS: Readonly<Record<EntryAffordance, string>>;
|
|
39
|
+
/** Fill an affordance's caption template. PURE, and pure on purpose: the caller supplies values it has ALREADY
|
|
40
|
+
* resolved (the plugin resolves the die through `resolveScalingDie` at the owner's class level, exactly as the
|
|
41
|
+
* shipped spend control resolves its own "(d8)" label), so no renderer ever holds the sentence and no engine
|
|
42
|
+
* module ever needs the character. A placeholder with no value is left VERBATIM rather than printed as
|
|
43
|
+
* "undefined". */
|
|
44
|
+
export declare function formatAffordanceCaption(affordance: EntryAffordance, values: {
|
|
45
|
+
amount: number;
|
|
46
|
+
die: string;
|
|
47
|
+
}): string;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AFFORDANCE_CAPTIONS,
|
|
3
|
+
RENDERING_HINT_AFFORDANCE,
|
|
4
|
+
RENDERING_HINT_LAYOUT,
|
|
5
|
+
deriveEntryAffordance,
|
|
6
|
+
derivePoolLayout,
|
|
7
|
+
formatAffordanceCaption
|
|
8
|
+
} from "../chunk-PP2UHLBA.js";
|
|
9
|
+
export {
|
|
10
|
+
AFFORDANCE_CAPTIONS,
|
|
11
|
+
RENDERING_HINT_AFFORDANCE,
|
|
12
|
+
RENDERING_HINT_LAYOUT,
|
|
13
|
+
deriveEntryAffordance,
|
|
14
|
+
derivePoolLayout,
|
|
15
|
+
formatAffordanceCaption
|
|
16
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* R4-G3a §5.2 · the tag mechanism's DATA tables: the single source of every roll/outcome tag
|
|
3
|
+
* TEXT the plugin's three chip surfaces render.
|
|
4
|
+
*
|
|
5
|
+
* Invariant 3: captions and tag texts derive from the effect's own fields through ONE
|
|
6
|
+
* data-shaped table per concern; a closed vocabulary `switch` on game data inside a component is
|
|
7
|
+
* the smell this replaces (all three surfaces spelled `mode === "advantage" ? "ADV" : "DIS"`,
|
|
8
|
+
* which renders "DIS" for a `reroll` the moment `mode` widens: a green tree with a false chip).
|
|
9
|
+
*
|
|
10
|
+
* `Record<RollModifierMode, …>` / `Record<RollKind, …>` are load-bearing: the aliases come from
|
|
11
|
+
* `pc.types.ts`, so widening `RollModifierEntry.mode` without extending these tables is a COMPILE
|
|
12
|
+
* error, not a silent misrender (§14 row 8i's control).
|
|
13
|
+
*
|
|
14
|
+
* `ROLL_MODE_WORD` and `ROLL_NOUN` are the PROSE halves (Task 3 consumes them for feature-card
|
|
15
|
+
* captions); `ROLL_MODE_TAG` is the terse chip half.
|
|
16
|
+
*
|
|
17
|
+
* `ROLL_NOUN` is keyed `RollKind | "any"`, one member wider than the folded `RollModifierEntry`.
|
|
18
|
+
* The fold FANS OUT `roll: "any"` into one entry per roll type (§6.2.1), so no chip surface ever
|
|
19
|
+
* sees it; the RAW effect on a feature row still carries it, and Task 3 captions raw effects. Its
|
|
20
|
+
* noun is "rolls" rather than a stand-in member: an `any` modifier covers checks, saves AND attacks
|
|
21
|
+
* at once, so borrowing "ability checks" for it understates the scope in prose.
|
|
22
|
+
*
|
|
23
|
+
* Never an "EVA" literal for the outcome tag:
|
|
24
|
+
* Evasion is only one of four bearers, and Spellfire Sorcery is not Evasion.
|
|
25
|
+
*/
|
|
26
|
+
import type { RollModifierMode, RollKind, SaveOutcome } from "./pc.types.js";
|
|
27
|
+
export declare const ROLL_MODE_TAG: Record<RollModifierMode, string>;
|
|
28
|
+
export declare const ROLL_MODE_WORD: Record<RollModifierMode, string>;
|
|
29
|
+
export declare const ROLL_NOUN: Record<RollKind | "any", string>;
|
|
30
|
+
export declare const AUTO_FAIL_TAG = "AUTO-FAIL";
|
|
31
|
+
/** R4-G7 T8 RIDER-20 (F-ADV) · the ONE glyph a CONDITIONAL tag appends to its text: a `roll-modifier` entry that carries a
|
|
32
|
+
* `condition`, or a `scope` the normaliser could not map (the qualifier the converter left in `scope`), and a `save-outcome`
|
|
33
|
+
* entry that carries a `condition`. `ADV` alone reads "always"; `ADV*` says "only sometimes, hover for when". The chip
|
|
34
|
+
* carriers append it to the `ROLL_MODE_TAG` / `saveOutcomeTag` text, so the glyph is spelled here once. */
|
|
35
|
+
export declare const CONDITIONAL_TAG_MARK = "*";
|
|
36
|
+
/** The closed `save-outcome` result vocabulary as display glyphs: how much damage you still take.
|
|
37
|
+
* `Record<SaveOutcome, string>` (the alias from pc.types.ts) so the union is spelled once. */
|
|
38
|
+
export declare const OUTCOME: Record<SaveOutcome, string>;
|
|
39
|
+
/** `{none, half}` → "0/½": success outcome over failure outcome. */
|
|
40
|
+
export declare const saveOutcomeTag: (onSuccess: SaveOutcome, onFailure: SaveOutcome) => string;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// src/pc/roll-tag-labels.ts
|
|
2
|
+
var ROLL_MODE_TAG = { advantage: "ADV", disadvantage: "DIS", reroll: "RR", "add-d4": "+D4" };
|
|
3
|
+
var ROLL_MODE_WORD = { advantage: "advantage", disadvantage: "disadvantage", reroll: "a reroll", "add-d4": "+1d4" };
|
|
4
|
+
var ROLL_NOUN = { "ability-check": "ability checks", "saving-throw": "saving throws", attack: "attack rolls", any: "rolls" };
|
|
5
|
+
var AUTO_FAIL_TAG = "AUTO-FAIL";
|
|
6
|
+
var CONDITIONAL_TAG_MARK = "*";
|
|
7
|
+
var OUTCOME = { none: "0", half: "\xBD", full: "1" };
|
|
8
|
+
var saveOutcomeTag = (onSuccess, onFailure) => `${OUTCOME[onSuccess]}/${OUTCOME[onFailure]}`;
|
|
9
|
+
export {
|
|
10
|
+
AUTO_FAIL_TAG,
|
|
11
|
+
CONDITIONAL_TAG_MARK,
|
|
12
|
+
OUTCOME,
|
|
13
|
+
ROLL_MODE_TAG,
|
|
14
|
+
ROLL_MODE_WORD,
|
|
15
|
+
ROLL_NOUN,
|
|
16
|
+
saveOutcomeTag
|
|
17
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ResolvedSpell } from "./pc.types.js";
|
|
2
|
+
/** R4-G3b §6 · ONE data-shaped routing descriptor per ResolvedSpell.source, read by the plugin's Spells-tab components in
|
|
3
|
+
* place of thirteen hardcoded `source ===` arms (the standing rule: policy from data, never a vocabulary switch in a
|
|
4
|
+
* component). No `label` (nothing renders a source caption; a provenance caption is G8's) and no `removable` (that is
|
|
5
|
+
* ResolvedSpell.persisted: membership in character.spells.known). `domain` is declared but NO grant producer
|
|
6
|
+
* hardcodes it; the one thing that reaches a sheet carrying it is a hand-authored `spells.known[].source:
|
|
7
|
+
* domain`, permitted by pc.schema.ts and passed through by normalizeKnownSpell (pc.spellcasting.ts). */
|
|
8
|
+
export interface SpellSourceDescriptor {
|
|
9
|
+
/** The row's DC / attack bonus come from its own `ability` when it carries one, not from a class. */
|
|
10
|
+
ownAbility: boolean;
|
|
11
|
+
/** Which surface the row belongs to: the class/grant spellbook sections, or Scrolls & Consumables. */
|
|
12
|
+
section: "spellbook" | "consumable";
|
|
13
|
+
/** A leveled row at a level the character owns no slot for gets its own free-cast block. */
|
|
14
|
+
freeCastWhenNoSlot: boolean;
|
|
15
|
+
/** The row is preparable/lockable in the Prepare list (and seeds its level filter chips). */
|
|
16
|
+
showInPrepare: boolean;
|
|
17
|
+
/** The row is a grant, so it lifts the Spells tab's "No Spellcasting" empty state on its own. */
|
|
18
|
+
countsAsGranted: boolean;
|
|
19
|
+
}
|
|
20
|
+
export declare const SPELL_SOURCE: Record<ResolvedSpell["source"], SpellSourceDescriptor>;
|
|
21
|
+
export declare const spellSource: (s: Pick<ResolvedSpell, "source">) => SpellSourceDescriptor;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// src/pc/spell-source.ts
|
|
2
|
+
var SPELL_SOURCE = {
|
|
3
|
+
class: { ownAbility: false, section: "spellbook", freeCastWhenNoSlot: false, showInPrepare: true, countsAsGranted: false },
|
|
4
|
+
feat: { ownAbility: true, section: "spellbook", freeCastWhenNoSlot: true, showInPrepare: true, countsAsGranted: true },
|
|
5
|
+
item: { ownAbility: false, section: "consumable", freeCastWhenNoSlot: false, showInPrepare: false, countsAsGranted: true },
|
|
6
|
+
race: { ownAbility: true, section: "spellbook", freeCastWhenNoSlot: true, showInPrepare: true, countsAsGranted: true },
|
|
7
|
+
domain: { ownAbility: false, section: "spellbook", freeCastWhenNoSlot: false, showInPrepare: true, countsAsGranted: false }
|
|
8
|
+
};
|
|
9
|
+
var spellSource = (s) => SPELL_SOURCE[s.source];
|
|
10
|
+
export {
|
|
11
|
+
SPELL_SOURCE,
|
|
12
|
+
spellSource
|
|
13
|
+
};
|
package/dist/race/race.codec.js
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
raceCodec
|
|
3
|
-
} from "../chunk-
|
|
4
|
-
import "../chunk-
|
|
5
|
-
import "../chunk-
|
|
6
|
-
import "../chunk-
|
|
3
|
+
} from "../chunk-XBQMCEI2.js";
|
|
4
|
+
import "../chunk-XGOFP7AQ.js";
|
|
5
|
+
import "../chunk-FDBWYMZK.js";
|
|
6
|
+
import "../chunk-4U55VNC7.js";
|
|
7
|
+
import "../chunk-4FWNK4FD.js";
|
|
7
8
|
import "../chunk-WYGD2UGN.js";
|
|
8
|
-
import "../chunk-
|
|
9
|
-
import "../chunk-
|
|
10
|
-
import "../chunk-
|
|
9
|
+
import "../chunk-YLL2QXY2.js";
|
|
10
|
+
import "../chunk-T26ZVCL5.js";
|
|
11
|
+
import "../chunk-WPWOHGPI.js";
|
|
12
|
+
import "../chunk-UA5KS2PL.js";
|
|
11
13
|
export {
|
|
12
14
|
raceCodec
|
|
13
15
|
};
|
package/dist/race/race.parser.js
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
2
|
parseRace
|
|
3
|
-
} from "../chunk-
|
|
4
|
-
import "../chunk-
|
|
5
|
-
import "../chunk-
|
|
3
|
+
} from "../chunk-XGOFP7AQ.js";
|
|
4
|
+
import "../chunk-FDBWYMZK.js";
|
|
5
|
+
import "../chunk-4U55VNC7.js";
|
|
6
|
+
import "../chunk-4FWNK4FD.js";
|
|
6
7
|
import "../chunk-WYGD2UGN.js";
|
|
7
|
-
import "../chunk-
|
|
8
|
-
import "../chunk-
|
|
9
|
-
import "../chunk-
|
|
8
|
+
import "../chunk-YLL2QXY2.js";
|
|
9
|
+
import "../chunk-T26ZVCL5.js";
|
|
10
|
+
import "../chunk-WPWOHGPI.js";
|
|
11
|
+
import "../chunk-UA5KS2PL.js";
|
|
10
12
|
export {
|
|
11
13
|
parseRace
|
|
12
14
|
};
|
|
@@ -1,4 +1,23 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
/** Exported so the SRD overlay validates AUTHORED fixed increases against the
|
|
3
|
+
* FIXED ARM canonical output is validated against, derived from this one
|
|
4
|
+
* definition so the two cannot drift. Note the precise relationship:
|
|
5
|
+
* `raceEntitySchema` below validates `ability_score_increases` with `asiSchema`,
|
|
6
|
+
* the UNION, of which this is one arm · `overlay.schema.ts` deliberately narrows
|
|
7
|
+
* to this arm alone, because the choice-shaped arm folds nothing at runtime
|
|
8
|
+
* (`flattenRaceAsi` reads only `"ability" in asi`), so rejecting it at authoring
|
|
9
|
+
* time is a guard, not a limitation. */
|
|
10
|
+
export declare const fixedAsiSchema: z.ZodObject<{
|
|
11
|
+
ability: z.ZodEnum<{
|
|
12
|
+
str: "str";
|
|
13
|
+
dex: "dex";
|
|
14
|
+
con: "con";
|
|
15
|
+
int: "int";
|
|
16
|
+
wis: "wis";
|
|
17
|
+
cha: "cha";
|
|
18
|
+
}>;
|
|
19
|
+
amount: z.ZodNumber;
|
|
20
|
+
}, z.core.$strip>;
|
|
2
21
|
export declare const raceEntitySchema: z.ZodObject<{
|
|
3
22
|
slug: z.ZodString;
|
|
4
23
|
name: z.ZodString;
|
|
@@ -10,8 +29,8 @@ export declare const raceEntitySchema: z.ZodObject<{
|
|
|
10
29
|
description: z.ZodString;
|
|
11
30
|
size: z.ZodEnum<{
|
|
12
31
|
medium: "medium";
|
|
13
|
-
tiny: "tiny";
|
|
14
32
|
small: "small";
|
|
33
|
+
tiny: "tiny";
|
|
15
34
|
large: "large";
|
|
16
35
|
huge: "huge";
|
|
17
36
|
}>;
|
|
@@ -64,4 +83,35 @@ export declare const raceEntitySchema: z.ZodObject<{
|
|
|
64
83
|
traits: z.ZodArray<z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>;
|
|
65
84
|
choices: z.ZodOptional<z.ZodArray<z.ZodType<import("../index.js").Choice, unknown, z.core.$ZodTypeInternals<import("../index.js").Choice, unknown>>>>;
|
|
66
85
|
subspecies_of: z.ZodOptional<z.ZodString>;
|
|
86
|
+
rendering_hint: z.ZodOptional<z.ZodString>;
|
|
87
|
+
has_fluff: z.ZodOptional<z.ZodBoolean>;
|
|
88
|
+
has_fluff_images: z.ZodOptional<z.ZodBoolean>;
|
|
89
|
+
creature_type: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
90
|
+
creature_type_tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
91
|
+
additional_spells: z.ZodOptional<z.ZodUnion<readonly [z.ZodArray<z.ZodObject<{
|
|
92
|
+
name: z.ZodOptional<z.ZodString>;
|
|
93
|
+
ability: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
94
|
+
choose: z.ZodArray<z.ZodString>;
|
|
95
|
+
}, z.core.$strip>]>>;
|
|
96
|
+
known: z.ZodOptional<z.ZodUnknown>;
|
|
97
|
+
innate: z.ZodOptional<z.ZodUnknown>;
|
|
98
|
+
prepared: z.ZodOptional<z.ZodUnknown>;
|
|
99
|
+
expanded: z.ZodOptional<z.ZodUnknown>;
|
|
100
|
+
resourceName: z.ZodOptional<z.ZodString>;
|
|
101
|
+
}, z.core.$strip>>, z.ZodObject<{
|
|
102
|
+
name: z.ZodOptional<z.ZodString>;
|
|
103
|
+
ability: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
104
|
+
choose: z.ZodArray<z.ZodString>;
|
|
105
|
+
}, z.core.$strip>]>>;
|
|
106
|
+
known: z.ZodOptional<z.ZodUnknown>;
|
|
107
|
+
innate: z.ZodOptional<z.ZodUnknown>;
|
|
108
|
+
prepared: z.ZodOptional<z.ZodUnknown>;
|
|
109
|
+
expanded: z.ZodOptional<z.ZodUnknown>;
|
|
110
|
+
resourceName: z.ZodOptional<z.ZodString>;
|
|
111
|
+
}, z.core.$strip>]>>;
|
|
112
|
+
trait_tags: z.ZodOptional<z.ZodUnknown>;
|
|
113
|
+
lineage: z.ZodOptional<z.ZodUnknown>;
|
|
114
|
+
height_and_weight: z.ZodOptional<z.ZodUnknown>;
|
|
115
|
+
sound_clip: z.ZodOptional<z.ZodUnknown>;
|
|
116
|
+
image: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
|
|
67
117
|
}, z.core.$strip>;
|
package/dist/race/race.schema.js
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
|
+
fixedAsiSchema,
|
|
2
3
|
raceEntitySchema
|
|
3
|
-
} from "../chunk-
|
|
4
|
-
import "../chunk-
|
|
4
|
+
} from "../chunk-FDBWYMZK.js";
|
|
5
|
+
import "../chunk-4FWNK4FD.js";
|
|
5
6
|
import "../chunk-WYGD2UGN.js";
|
|
6
|
-
import "../chunk-
|
|
7
|
-
import "../chunk-
|
|
8
|
-
import "../chunk-
|
|
7
|
+
import "../chunk-YLL2QXY2.js";
|
|
8
|
+
import "../chunk-T26ZVCL5.js";
|
|
9
|
+
import "../chunk-WPWOHGPI.js";
|
|
10
|
+
import "../chunk-UA5KS2PL.js";
|
|
9
11
|
export {
|
|
12
|
+
fixedAsiSchema,
|
|
10
13
|
raceEntitySchema
|
|
11
14
|
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** R4-G3b §5.2.9 · the STRUCTURAL pseudo-choices of a race entry: Size / Speed / Darkvision are surfaced as glance tiles
|
|
2
|
+
* and are not content. Shared by the plugin's two trait-name folds (keyed on TRAIT NAMES, lowercased) and by the
|
|
3
|
+
* resolver's `additional_spells` race gate (keyed on select-inline CHOICE IDS; on the corpus only `size` occurs as an
|
|
4
|
+
* id, 18 carriers, 17 saved by this exemption). A measured v1 exception to the schema-not-renderer rule: it must never
|
|
5
|
+
* grow into an allowlist of lineage ids (the structural replacement is the NEXT-REGEN / G7 ask). NOT imported by any
|
|
6
|
+
* schema, parser, codec or srd module (the T6/T12 grep guard keeps it out of the generators graph). */
|
|
7
|
+
export declare const RACE_STRUCTURAL_PSEUDO: ReadonlySet<string>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Feature, Ability, Speed, Choice } from "@archivist-gg/dnd5e";
|
|
2
2
|
import type { Edition } from "@archivist-gg/dnd5e/types/edition";
|
|
3
|
+
import type { AdditionalSpellsEntry } from "@archivist-gg/dnd5e/schemas/entity-extras-schema";
|
|
3
4
|
export type Size = "tiny" | "small" | "medium" | "large" | "huge";
|
|
4
5
|
export type FixedAbilityIncrease = {
|
|
5
6
|
ability: Ability;
|
|
@@ -41,4 +42,23 @@ export interface RaceEntity {
|
|
|
41
42
|
traits: Feature[];
|
|
42
43
|
choices?: Choice[];
|
|
43
44
|
subspecies_of?: string;
|
|
45
|
+
/** Converter/bundle extras declared by race.schema.ts §2.3. Every one is optional: none is
|
|
46
|
+
* read by the pc pipeline today, and declaring them is what stops the parser silently
|
|
47
|
+
* dropping them (the "declare or lose" rule). */
|
|
48
|
+
rendering_hint?: string;
|
|
49
|
+
has_fluff?: boolean;
|
|
50
|
+
has_fluff_images?: boolean;
|
|
51
|
+
creature_type?: string[];
|
|
52
|
+
creature_type_tags?: string[];
|
|
53
|
+
/** DUAL ARITY (§2.8): the converter emits an array on 109 docs, the shipped SRD bundle a bare
|
|
54
|
+
* object on 3 (`SRD 2024/Races/{Elf,Tiefling}.md`, `SRD 5e/Races/Tiefling.md`). */
|
|
55
|
+
additional_spells?: AdditionalSpellsEntry[] | AdditionalSpellsEntry;
|
|
56
|
+
/** The four RAW 5etools passthroughs: `unknown` mirrors the schema's `z.unknown()`. Today's
|
|
57
|
+
* variant set is a snapshot, not a contract, so the type stays maximally loose. */
|
|
58
|
+
trait_tags?: unknown;
|
|
59
|
+
lineage?: unknown;
|
|
60
|
+
height_and_weight?: unknown;
|
|
61
|
+
sound_clip?: unknown;
|
|
62
|
+
/** One wikilink, or an array of them for the multi-fluff-image emit. */
|
|
63
|
+
image?: string | string[];
|
|
44
64
|
}
|
|
@@ -35,4 +35,9 @@ export declare const attackSchema: z.ZodObject<{
|
|
|
35
35
|
reach: z.ZodOptional<z.ZodNumber>;
|
|
36
36
|
}, z.core.$strip>>;
|
|
37
37
|
condition: z.ZodOptional<z.ZodString>;
|
|
38
|
+
bonus: z.ZodOptional<z.ZodNumber>;
|
|
39
|
+
extra_damage: z.ZodOptional<z.ZodObject<{
|
|
40
|
+
dice: z.ZodString;
|
|
41
|
+
type: z.ZodString;
|
|
42
|
+
}, z.core.$strip>>;
|
|
38
43
|
}, z.core.$strip>;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/** THE caster-type vocabulary, declared once (R4-G1a D6a). "artificer" is a fifth progression (level-1 slots,
|
|
3
|
+
* then the half-caster table; multiclass contributes half its levels rounded UP; prepared count is Int mod +
|
|
4
|
+
* floor(level/2) when no table column supplies it). The XPHB Paladin and Ranger carry it in the converter's
|
|
5
|
+
* emission. Imported by the class and subclass schemas, the class types, pc.types and the generator's overlay
|
|
6
|
+
* schema and class merger: never redeclare it. */
|
|
7
|
+
export declare const casterTypeEnum: z.ZodEnum<{
|
|
8
|
+
half: "half";
|
|
9
|
+
full: "full";
|
|
10
|
+
pact: "pact";
|
|
11
|
+
third: "third";
|
|
12
|
+
artificer: "artificer";
|
|
13
|
+
}>;
|
|
14
|
+
export type CasterType = z.infer<typeof casterTypeEnum>;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* Shared leaf schemas for the entity "extras" the converter and the SRD bundle
|
|
4
|
+
* emit on more than one root. Six root schemas will import from here (race,
|
|
5
|
+
* feat, optional-feature, background, class, subclass; the wiring lands in T2/T3)
|
|
6
|
+
* so a shape is declared ONCE.
|
|
7
|
+
*
|
|
8
|
+
* Everything here is additive and `.optional()` at the point of use: no
|
|
9
|
+
* `.default()`, no tightening, no new required field. A raw-blob leaf is always
|
|
10
|
+
* `z.unknown().optional()` — a bare `z.unknown()` inside `z.object` is NOT
|
|
11
|
+
* optional under zod v4 (`safeParse({})` fails `expected nonoptional`).
|
|
12
|
+
*/
|
|
13
|
+
/** Images-ON emit (scripts/lib/image-format.ts): one wikilink string, or an array for ≥2 fluff
|
|
14
|
+
* images; `thumbnail` monster-only. ZERO carriers on the frozen images-OFF tree — see §9.4.
|
|
15
|
+
* NO .nonempty() on the array arm (gate1-r1 f13): the variant set is unestablished (Gate 0
|
|
16
|
+
* finding 25) and the phase's own rule — a new declaration must be INCAPABLE of refusing —
|
|
17
|
+
* outranks a speculative arity constraint on the one key a future convert:images run feeds. */
|
|
18
|
+
export declare const imageField: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
|
|
19
|
+
/** 5etools additionalSpells. Key-set measured COMPLETE over all 52 distinct sets on 5 roots:
|
|
20
|
+
* {ability, expanded, innate, known, name, prepared, resourceName} (Gate 0 finding 5).
|
|
21
|
+
* Loose leaves are deliberate: level keys are arbitrary strings ("1","s0","_","1e","pb","cha"…),
|
|
22
|
+
* the known.'1' string-keying is converter-owned (A §7.2) and passes through VERBATIM. */
|
|
23
|
+
export declare const additionalSpellsEntrySchema: z.ZodObject<{
|
|
24
|
+
name: z.ZodOptional<z.ZodString>;
|
|
25
|
+
ability: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
26
|
+
choose: z.ZodArray<z.ZodString>;
|
|
27
|
+
}, z.core.$strip>]>>;
|
|
28
|
+
known: z.ZodOptional<z.ZodUnknown>;
|
|
29
|
+
innate: z.ZodOptional<z.ZodUnknown>;
|
|
30
|
+
prepared: z.ZodOptional<z.ZodUnknown>;
|
|
31
|
+
expanded: z.ZodOptional<z.ZodUnknown>;
|
|
32
|
+
resourceName: z.ZodOptional<z.ZodString>;
|
|
33
|
+
}, z.core.$strip>;
|
|
34
|
+
/** optionalfeature_progression / feat_progression containers. Measured distribution (finding 4):
|
|
35
|
+
* `progression` is a record on 42 of 46 containers (keys numeric strings + "*", values number) and
|
|
36
|
+
* an ARRAY (number[], len 20) on class.optionalfeature_progression ONLY (4 docs: both PHB Warlocks,
|
|
37
|
+
* TCE + Eberron Artificer). `featureType` (camelCase) is the ONLY spelling on all 13 subclass
|
|
38
|
+
* optionalfeature_progression containers; `feature_type` (snake) on class/feat/optional-feature —
|
|
39
|
+
* true of their optionalfeature_progression containers; `class.feat_progression`'s 16 containers
|
|
40
|
+
* carry neither spelling; `required` on 2 subclass docs ({"3": ["Elemental Attunement|PHB"]}).
|
|
41
|
+
* Union order is SAFE
|
|
42
|
+
* (executed: record.safeParse(array) fails invalid_type). Distribution recorded in T0's census
|
|
43
|
+
* baseline — NO test asserts it; §9.3 characterises the SHAPES only. */
|
|
44
|
+
export declare const progressionSchema: z.ZodObject<{
|
|
45
|
+
name: z.ZodString;
|
|
46
|
+
progression: z.ZodUnion<readonly [z.ZodRecord<z.ZodString, z.ZodNumber>, z.ZodArray<z.ZodNumber>]>;
|
|
47
|
+
feature_type: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
48
|
+
featureType: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
49
|
+
category: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
50
|
+
required: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString>>>;
|
|
51
|
+
}, z.core.$strip>;
|
|
52
|
+
export type AdditionalSpellsEntry = z.infer<typeof additionalSpellsEntrySchema>;
|
|
53
|
+
export type ProgressionEntry = z.infer<typeof progressionSchema>;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import type { EquipmentGrant, EquipmentOption, StartingEquipmentEntry, StartingGold } from "../types/equipment-grant.js";
|
|
3
|
+
/** Every arm stays `.strict()`: one stray key refuses the whole document on purpose (the builder's render path
|
|
4
|
+
* maps over grants). The three passthrough keys are DECLARED, not tolerated. */
|
|
3
5
|
export declare const equipmentGrantSchema: z.ZodType<EquipmentGrant>;
|
|
4
6
|
export declare const equipmentOptionSchema: z.ZodType<EquipmentOption>;
|
|
5
7
|
export declare const startingEquipmentEntrySchema: z.ZodType<StartingEquipmentEntry>;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/** R4-G3a §10.2.1: the SRD bundle spells a race trait's action cost `action_cost`; the canonical key is
|
|
2
|
+
* `action`. Alias fills a hole, declared wins, never deleted (the `armor.parser.ts` strength_required
|
|
3
|
+
* precedent; the resolver's optional-feature grant alias is the in-repo precedent for the KEY).
|
|
4
|
+
*
|
|
5
|
+
* No `package.json` exports entry, because the plugin never imports this module: the sheet's resolver
|
|
6
|
+
* applies the alias at resolve time through `withResolvedActionCost` (R4-G3a Task 12), and the ONE plugin
|
|
7
|
+
* site that reads a race trait's action cost off the RAW registry entity (the race block's tracker gate,
|
|
8
|
+
* R4-G3b §11) reads BOTH spellings with a nullish fallback rather than importing this helper. Not imported
|
|
9
|
+
* is NOT the same as parser-internal, and the module is not parser-internal: MEASURED 2026-09-04, every
|
|
10
|
+
* export here reaches the plugin's built `main.js`, `withResolvedActionCost` through `pc/pc.resolver.ts`
|
|
11
|
+
* and the raw-YAML aliasers through the race / class / subclass parsers, which the plugin pulls in with
|
|
12
|
+
* `dnd5ePack` (pack → entity types → codecs → parsers). What is parser-only is where the aliasers RUN:
|
|
13
|
+
* their three call sites are `race.parser.ts`, `class.parser.ts` and `subclass.parser.ts`, so they fire on
|
|
14
|
+
* the entity-note codec path and never on the sheet's, which reads RAW registry objects.
|
|
15
|
+
*
|
|
16
|
+
* This one is applied on the RAW YAML object before `safeParse`, so the aliased value goes through the
|
|
17
|
+
* same enum validation as a declared one (an out-of-vocabulary `action_cost` refuses the document rather
|
|
18
|
+
* than smuggling a bad `action` past the schema). */
|
|
19
|
+
export declare function aliasFeatureActionCost(f: Record<string, unknown>): void;
|
|
20
|
+
/** The list form: race `traits[]`, and one level's `features_by_level[lvl]` array. Non-arrays and
|
|
21
|
+
* non-object members are left alone; a malformed document is the schema's business, not ours. */
|
|
22
|
+
export declare function aliasFeatureListActionCost(list: unknown): void;
|
|
23
|
+
/** The `features_by_level` record form, shared by the class and subclass parsers. Zero bundle
|
|
24
|
+
* carriers live here today; it is aliased for symmetry so a future class-side `action_cost` is
|
|
25
|
+
* not a second silent routing bug. */
|
|
26
|
+
export declare function aliasFeaturesByLevelActionCost(byLevel: unknown): void;
|
|
27
|
+
/** Resolve-time mirror of `aliasFeatureActionCost` (R4-G3a Task 12): the PC sheet resolves RAW registry entities
|
|
28
|
+
* (never parsed by dnd5e), so the parser-side alias is invisible to it. Returns the same object when nothing applies
|
|
29
|
+
* (registry entities are shared and must not be mutated), else a shallow copy with `action` filled from
|
|
30
|
+
* `action_cost`. Declared `action` wins. */
|
|
31
|
+
export declare function withResolvedActionCost<T extends {
|
|
32
|
+
action?: unknown;
|
|
33
|
+
action_cost?: unknown;
|
|
34
|
+
}>(f: T): T;
|