@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.
Files changed (260) hide show
  1. package/LICENSES/SRD.md +25 -6
  2. package/dist/armor/armor.codec.js +4 -3
  3. package/dist/armor/armor.parser.js +3 -2
  4. package/dist/armor/armor.schema.d.ts +4 -0
  5. package/dist/armor/armor.schema.js +2 -1
  6. package/dist/armor/armor.types.d.ts +8 -0
  7. package/dist/background/background.codec.js +7 -6
  8. package/dist/background/background.parser.js +6 -5
  9. package/dist/background/background.schema.d.ts +34 -0
  10. package/dist/background/background.schema.js +9 -6
  11. package/dist/background/background.types.d.ts +22 -0
  12. package/dist/{chunk-4TIJKN6O.js → chunk-23LZLBJK.js} +1 -1
  13. package/dist/{chunk-AFKTJXRA.js → chunk-2DFENQIJ.js} +18 -0
  14. package/dist/chunk-2FRUSVZS.js +489 -0
  15. package/dist/chunk-4FWNK4FD.js +159 -0
  16. package/dist/chunk-4U55VNC7.js +22 -0
  17. package/dist/{chunk-4JHOHWBI.js → chunk-4XTNPNQB.js} +1 -1
  18. package/dist/{chunk-HCP3GMHS.js → chunk-5N2GW72F.js} +15 -2
  19. package/dist/{chunk-42Y5IJKT.js → chunk-5U5FFFA3.js} +5 -1
  20. package/dist/{chunk-4F6AIZ36.js → chunk-5XMQPTHD.js} +1 -1
  21. package/dist/{chunk-GJOI2GHP.js → chunk-6GNXYAYP.js} +1 -1
  22. package/dist/chunk-6PKV5V2H.js +178 -0
  23. package/dist/{chunk-66XXW2Z2.js → chunk-6PXTNCBP.js} +2 -2
  24. package/dist/chunk-6X2NV665.js +33 -0
  25. package/dist/{chunk-LV4SNWZQ.js → chunk-6X4KUDMU.js} +8 -1
  26. package/dist/{chunk-ZMR77DDL.js → chunk-AW3EHF3L.js} +1 -1
  27. package/dist/chunk-CJYCVNW2.js +7 -0
  28. package/dist/chunk-COEOOQX2.js +133 -0
  29. package/dist/{chunk-XTIQWSFM.js → chunk-D5U7GMPX.js} +1 -1
  30. package/dist/{chunk-RAWJTA45.js → chunk-DEEHHLAP.js} +1 -1
  31. package/dist/chunk-DPUJDOKV.js +365 -0
  32. package/dist/{chunk-73HOFQQ5.js → chunk-ESS46GR4.js} +1 -1
  33. package/dist/chunk-EVMUJYUD.js +195 -0
  34. package/dist/{chunk-2BWAID3Y.js → chunk-FDBWYMZK.js} +29 -3
  35. package/dist/{chunk-K6Q5OUGK.js → chunk-GFZ7PITJ.js} +86 -10
  36. package/dist/chunk-H7KBLR4X.js +81 -0
  37. package/dist/{chunk-L7E2UT5A.js → chunk-HB7XZXDK.js} +5 -1
  38. package/dist/{chunk-VTYUBINW.js → chunk-HJ5EEZ47.js} +1 -1
  39. package/dist/{chunk-6NK2MUD3.js → chunk-HZA7OE7N.js} +9 -2
  40. package/dist/{chunk-A4WENOUQ.js → chunk-I2NDWFDD.js} +52 -8
  41. package/dist/{chunk-RSDRMH54.js → chunk-IMZFOOVL.js} +1 -1
  42. package/dist/{chunk-3DZ74AKK.js → chunk-IN4M4X7P.js} +8 -2
  43. package/dist/chunk-IUAAXXNO.js +58 -0
  44. package/dist/{chunk-XJNECUPT.js → chunk-JC5UNIVM.js} +19 -0
  45. package/dist/chunk-JJ46T5XX.js +297 -0
  46. package/dist/{chunk-TUIFSVLI.js → chunk-JRDPUDT5.js} +30 -3
  47. package/dist/{chunk-24GFQU7T.js → chunk-JSZ4H6AQ.js} +1 -1
  48. package/dist/chunk-KU3YLF6D.js +106 -0
  49. package/dist/{chunk-5INR4NSL.js → chunk-LDDCNPHD.js} +1 -1
  50. package/dist/{chunk-DZXSWSBP.js → chunk-LMBAEIP6.js} +1 -1
  51. package/dist/chunk-LVQLWRCU.js +15 -0
  52. package/dist/chunk-MI7P3NX3.js +161 -0
  53. package/dist/chunk-O4SRD3J5.js +165 -0
  54. package/dist/{chunk-EMOORSQ7.js → chunk-OSQFPGLM.js} +45 -6
  55. package/dist/chunk-OZP6JFGT.js +162 -0
  56. package/dist/{chunk-NAEPSZAM.js → chunk-PDJSUH24.js} +24 -2
  57. package/dist/chunk-PP2UHLBA.js +50 -0
  58. package/dist/chunk-PVCEA4HZ.js +6 -0
  59. package/dist/{chunk-XLSVNUTK.js → chunk-R3VAKWKW.js} +1 -1
  60. package/dist/chunk-RIXI5D3R.js +89 -0
  61. package/dist/chunk-RLGQ5PZZ.js +16 -0
  62. package/dist/chunk-S7REMWW4.js +21 -0
  63. package/dist/{chunk-7VJ6BOA5.js → chunk-SMLXZUBH.js} +9 -1
  64. package/dist/{chunk-NXSWH3AE.js → chunk-T26ZVCL5.js} +1 -1
  65. package/dist/chunk-TOM66P2P.js +38 -0
  66. package/dist/chunk-UA5KS2PL.js +26 -0
  67. package/dist/{chunk-N6N74K6X.js → chunk-UBBKSYBY.js} +1 -1
  68. package/dist/{chunk-353WXS6S.js → chunk-UIRMA5KM.js} +1 -1
  69. package/dist/{chunk-GE4TLPWM.js → chunk-US5IKYCW.js} +1 -1
  70. package/dist/chunk-UXPGW4TI.js +101 -0
  71. package/dist/chunk-VQAXTIBW.js +100 -0
  72. package/dist/{chunk-WP2CX2JO.js → chunk-WELIKLZF.js} +22 -1
  73. package/dist/chunk-WPWOHGPI.js +172 -0
  74. package/dist/{chunk-GZ46OVGZ.js → chunk-WSVMLNTO.js} +1 -1
  75. package/dist/{chunk-4LZJXJJS.js → chunk-WXWPK3LI.js} +6 -2
  76. package/dist/{chunk-ZZGEVJKX.js → chunk-XBQMCEI2.js} +1 -1
  77. package/dist/{chunk-PHQRGDRQ.js → chunk-XGOFP7AQ.js} +5 -1
  78. package/dist/chunk-XJ2F2WO6.js +8 -0
  79. package/dist/chunk-XQCSGNXE.js +1580 -0
  80. package/dist/chunk-YBLDE5CG.js +42 -0
  81. package/dist/{chunk-JEYQU3JT.js → chunk-YHYTW5QA.js} +2 -18
  82. package/dist/{chunk-TLYDBT5F.js → chunk-YJJTISBN.js} +64 -7
  83. package/dist/{chunk-PZOWBI3B.js → chunk-YLL2QXY2.js} +7 -2
  84. package/dist/{chunk-MDEJHMKK.js → chunk-ZONJ66NE.js} +26 -5
  85. package/dist/class/class.codec.js +12 -9
  86. package/dist/class/class.parser.js +11 -8
  87. package/dist/class/class.schema.d.ts +55 -3
  88. package/dist/class/class.schema.js +9 -7
  89. package/dist/class/class.types.d.ts +48 -3
  90. package/dist/condition/condition.codec.d.ts +9 -0
  91. package/dist/condition/condition.entity-type.d.ts +2 -0
  92. package/dist/condition/condition.parser.d.ts +13 -0
  93. package/dist/condition/condition.parser.js +7 -0
  94. package/dist/condition/condition.schema.d.ts +29 -0
  95. package/dist/condition/condition.types.d.ts +15 -0
  96. package/dist/condition/condition.types.js +0 -0
  97. package/dist/dnd/constants.d.ts +22 -0
  98. package/dist/dnd/constants.js +9 -3
  99. package/dist/dnd/formula-tags.js +2 -2
  100. package/dist/dnd/math.d.ts +26 -0
  101. package/dist/dnd/math.js +12 -2
  102. package/dist/dnd/prose-tags.js +1 -1
  103. package/dist/dnd/resource-formula.d.ts +36 -10
  104. package/dist/dnd/resource-formula.js +10 -155
  105. package/dist/dnd/srd-tag-converter.js +3 -3
  106. package/dist/dnd/tag-grammar.js +1 -1
  107. package/dist/dnd/warn-once.d.ts +2 -0
  108. package/dist/dnd/warn-once.js +8 -0
  109. package/dist/entities/base-item-resolver.js +2 -2
  110. package/dist/entities/slug.d.ts +13 -0
  111. package/dist/entities/slug.js +5 -3
  112. package/dist/entities/wikilink-display.d.ts +3 -0
  113. package/dist/entities/wikilink-display.js +10 -0
  114. package/dist/feat/feat.category-codes.d.ts +32 -0
  115. package/dist/feat/feat.category-codes.js +14 -0
  116. package/dist/feat/feat.codec.js +7 -5
  117. package/dist/feat/feat.parser.js +6 -4
  118. package/dist/feat/feat.schema.d.ts +230 -0
  119. package/dist/feat/feat.schema.js +5 -3
  120. package/dist/feat/feat.types.d.ts +37 -1
  121. package/dist/index.js +2120 -6923
  122. package/dist/item/item.ai-schema.d.ts +1 -1
  123. package/dist/item/item.codec.js +4 -3
  124. package/dist/item/item.enrichment.js +4 -4
  125. package/dist/item/item.parser.js +3 -2
  126. package/dist/item/item.schema.d.ts +69 -3
  127. package/dist/item/item.schema.js +2 -1
  128. package/dist/item/item.types.d.ts +69 -3
  129. package/dist/monster/monster.codec.d.ts +7 -6
  130. package/dist/monster/monster.enrichment.js +4 -4
  131. package/dist/monster/monster.format.d.ts +135 -0
  132. package/dist/monster/monster.format.js +78 -0
  133. package/dist/monster/monster.parser.d.ts +6 -1
  134. package/dist/monster/monster.parser.js +10 -1
  135. package/dist/monster/monster.schema.d.ts +369 -0
  136. package/dist/monster/monster.schema.js +34 -0
  137. package/dist/monster/monster.types.d.ts +200 -14
  138. package/dist/optional-feature/optional-feature.codec.js +6 -5
  139. package/dist/optional-feature/optional-feature.parser.js +5 -4
  140. package/dist/optional-feature/optional-feature.schema.d.ts +176 -0
  141. package/dist/optional-feature/optional-feature.schema.js +4 -3
  142. package/dist/pack.d.ts +1 -1
  143. package/dist/pc/conditions.constants.d.ts +0 -1
  144. package/dist/pc/conditions.constants.js +1 -3
  145. package/dist/pc/decision-recognizer.js +1 -1
  146. package/dist/pc/pc.additional-spells.d.ts +47 -0
  147. package/dist/pc/pc.additional-spells.js +23 -0
  148. package/dist/pc/pc.asi-flatten.d.ts +18 -0
  149. package/dist/pc/pc.decision-engine.d.ts +106 -5
  150. package/dist/pc/pc.decision-engine.js +28 -10
  151. package/dist/pc/pc.defense-normalize.d.ts +11 -0
  152. package/dist/pc/pc.defense-normalize.js +6 -0
  153. package/dist/pc/pc.equipment.d.ts +30 -1
  154. package/dist/pc/pc.equipment.js +12 -7
  155. package/dist/pc/pc.feature-effects.d.ts +225 -11
  156. package/dist/pc/pc.feature-effects.js +21 -5
  157. package/dist/pc/pc.parser.js +2 -2
  158. package/dist/pc/pc.pools.d.ts +11 -3
  159. package/dist/pc/pc.pools.js +9 -13
  160. package/dist/pc/pc.proficiencies.d.ts +60 -4
  161. package/dist/pc/pc.proficiencies.js +89 -37
  162. package/dist/pc/pc.proficiency-grants.d.ts +58 -0
  163. package/dist/pc/pc.proficiency-normalize.d.ts +29 -0
  164. package/dist/pc/pc.proficiency-normalize.js +12 -0
  165. package/dist/pc/pc.proficiency-query.d.ts +13 -0
  166. package/dist/pc/pc.proficiency-query.js +5 -1
  167. package/dist/pc/pc.recalc.d.ts +69 -14
  168. package/dist/pc/pc.recalc.js +291 -142
  169. package/dist/pc/pc.resolver.d.ts +34 -8
  170. package/dist/pc/pc.resolver.js +27 -12
  171. package/dist/pc/pc.resource-seed.d.ts +3 -2
  172. package/dist/pc/pc.resource-seed.js +19 -17
  173. package/dist/pc/pc.resources.d.ts +87 -0
  174. package/dist/pc/pc.resources.js +21 -0
  175. package/dist/pc/pc.rest.d.ts +10 -1
  176. package/dist/pc/pc.rest.js +66 -12
  177. package/dist/pc/pc.schema.d.ts +147 -7
  178. package/dist/pc/pc.schema.js +4 -2
  179. package/dist/pc/pc.slotting.js +3 -3
  180. package/dist/pc/pc.spellcasting.d.ts +80 -7
  181. package/dist/pc/pc.spellcasting.js +18 -6
  182. package/dist/pc/pc.table-column.d.ts +23 -0
  183. package/dist/pc/pc.table-column.js +13 -3
  184. package/dist/pc/pc.types.d.ts +253 -16
  185. package/dist/pc/pool-layout.d.ts +47 -0
  186. package/dist/pc/pool-layout.js +16 -0
  187. package/dist/pc/roll-scope.d.ts +2 -0
  188. package/dist/pc/roll-scope.js +8 -0
  189. package/dist/pc/roll-tag-labels.d.ts +40 -0
  190. package/dist/pc/roll-tag-labels.js +17 -0
  191. package/dist/pc/spell-source.d.ts +21 -0
  192. package/dist/pc/spell-source.js +13 -0
  193. package/dist/race/race.codec.js +9 -7
  194. package/dist/race/race.parser.js +8 -6
  195. package/dist/race/race.schema.d.ts +51 -1
  196. package/dist/race/race.schema.js +8 -5
  197. package/dist/race/race.structural.d.ts +7 -0
  198. package/dist/race/race.structural.js +6 -0
  199. package/dist/race/race.types.d.ts +20 -0
  200. package/dist/schemas/attack-schema.d.ts +5 -0
  201. package/dist/schemas/caster-type-schema.d.ts +14 -0
  202. package/dist/schemas/caster-type-schema.js +6 -0
  203. package/dist/schemas/choice-schema.js +2 -2
  204. package/dist/schemas/entity-extras-schema.d.ts +53 -0
  205. package/dist/schemas/entity-extras-schema.js +10 -0
  206. package/dist/schemas/equipment-grant-schema.d.ts +2 -0
  207. package/dist/schemas/equipment-grant-schema.js +1 -1
  208. package/dist/schemas/feature-alias.d.ts +34 -0
  209. package/dist/schemas/feature-effect-schema.d.ts +124 -0
  210. package/dist/schemas/feature-effect-schema.js +1 -1
  211. package/dist/schemas/feature-schema.d.ts +8 -0
  212. package/dist/schemas/feature-schema.js +6 -4
  213. package/dist/schemas/resource-schema.d.ts +43 -0
  214. package/dist/schemas/resource-schema.js +1 -1
  215. package/dist/schemas/selection-pool-schema.d.ts +2 -0
  216. package/dist/schemas/selection-pool-schema.js +1 -1
  217. package/dist/spell/spell.access.js +23 -3
  218. package/dist/spell/spell.codec.js +4 -3
  219. package/dist/spell/spell.enrichment.js +4 -4
  220. package/dist/spell/spell.parser.d.ts +30 -0
  221. package/dist/spell/spell.parser.js +9 -2
  222. package/dist/spell/spell.scaling.d.ts +27 -6
  223. package/dist/spell/spell.scaling.js +25 -6
  224. package/dist/spell/spell.schema.d.ts +44 -2
  225. package/dist/spell/spell.schema.js +2 -1
  226. package/dist/spell/spell.types.d.ts +14 -0
  227. package/dist/subclass/subclass.codec.d.ts +1 -1
  228. package/dist/subclass/subclass.codec.js +11 -8
  229. package/dist/subclass/subclass.parser.js +10 -7
  230. package/dist/subclass/subclass.schema.d.ts +54 -7
  231. package/dist/subclass/subclass.schema.js +8 -6
  232. package/dist/subclass/subclass.types.d.ts +20 -2
  233. package/dist/types/choice.d.ts +56 -0
  234. package/dist/types/choice.js +21 -3
  235. package/dist/types/equipment-grant.d.ts +8 -1
  236. package/dist/types/feature-effect.d.ts +78 -23
  237. package/dist/types/feature.d.ts +70 -1
  238. package/dist/types/optional-feature.types.d.ts +28 -0
  239. package/dist/types/resource.d.ts +21 -1
  240. package/dist/types/selection-pool.d.ts +17 -2
  241. package/dist/weapon/weapon.classify.js +2 -2
  242. package/dist/weapon/weapon.codec.js +4 -3
  243. package/dist/weapon/weapon.parser.js +3 -2
  244. package/dist/weapon/weapon.schema.d.ts +4 -0
  245. package/dist/weapon/weapon.schema.js +2 -1
  246. package/dist/weapon/weapon.types.d.ts +8 -0
  247. package/package.json +2 -2
  248. package/dist/chunk-5MZSB6OM.js +0 -1089
  249. package/dist/chunk-5XUXXAQJ.js +0 -30
  250. package/dist/chunk-7P65Q426.js +0 -158
  251. package/dist/chunk-AIRFC5NQ.js +0 -143
  252. package/dist/chunk-BH6AMZVY.js +0 -25
  253. package/dist/chunk-CZPMTQOY.js +0 -68
  254. package/dist/chunk-M2EMFD6S.js +0 -269
  255. package/dist/chunk-N2JE7BWL.js +0 -81
  256. package/dist/chunk-NXR3BD2V.js +0 -90
  257. package/dist/chunk-Q5K6LWBZ.js +0 -45
  258. package/dist/chunk-TZK36BU7.js +0 -38
  259. package/dist/chunk-W7HWMMBF.js +0 -46
  260. package/dist/chunk-Y4I74YEG.js +0 -33
@@ -0,0 +1,42 @@
1
+ // src/feat/feat.category-codes.ts
2
+ var FEAT_CATEGORY_CODE_LABELS = {
3
+ D: "Dragonmark",
4
+ G: "General",
5
+ O: "Origin",
6
+ FS: "Fighting Style",
7
+ EB: "Epic Boon",
8
+ DG: "Dark Gift",
9
+ "FS:P": "Fighting Style",
10
+ "FS:R": "Fighting Style"
11
+ };
12
+ function featCategoryLabel(code) {
13
+ var _a;
14
+ return (_a = FEAT_CATEGORY_CODE_LABELS[code]) != null ? _a : code;
15
+ }
16
+ var FEAT_PROGRESSION_CATEGORY = {
17
+ FS: "fighting-style",
18
+ "FS:P": "fighting-style",
19
+ "FS:R": "fighting-style",
20
+ EB: "epic-boon",
21
+ O: "origin",
22
+ G: "general"
23
+ };
24
+ var FEATURE_TYPE_FOR_CATEGORY = {
25
+ "fighting-style": "fighting_style"
26
+ };
27
+ function featProgressionCategory(codes) {
28
+ for (const code of codes != null ? codes : []) {
29
+ if (Object.prototype.hasOwnProperty.call(FEAT_PROGRESSION_CATEGORY, code)) {
30
+ return FEAT_PROGRESSION_CATEGORY[code];
31
+ }
32
+ }
33
+ return void 0;
34
+ }
35
+
36
+ export {
37
+ FEAT_CATEGORY_CODE_LABELS,
38
+ featCategoryLabel,
39
+ FEAT_PROGRESSION_CATEGORY,
40
+ FEATURE_TYPE_FOR_CATEGORY,
41
+ featProgressionCategory
42
+ };
@@ -1,24 +1,8 @@
1
1
  // src/pc/decision-recognizer.ts
2
2
  var DECISION_SIGNAL = [/\bchoose (one|two|three|a|an)\b/i, /\bof your choice\b/i, /\byour choice of\b/i];
3
- var ASI_OR_FEAT = {
4
- kind: "select-inline",
5
- id: "asi-or-feat",
6
- count: 1,
7
- options: [
8
- {
9
- value: "asi",
10
- label: "Ability Score Increase",
11
- choices: [{ kind: "ability-points", id: "asi", points: 2, max_per: 2 }]
12
- },
13
- {
14
- value: "feat",
15
- label: "Feat",
16
- choices: [{ kind: "select-entity", id: "feat", entity_type: "feat", count: 1 }]
17
- }
18
- ]
19
- };
3
+ var ASI_FEAT = { kind: "select-entity", id: "feat", entity_type: "feat", count: 1 };
20
4
  var TABLE = {
21
- "ability-score-improvement": [ASI_OR_FEAT],
5
+ "ability-score-improvement": [ASI_FEAT],
22
6
  "expertise": [{ kind: "select-proficiency", id: "expertise", count: 2, domain: "skill", from_proficient: true, expertise: true }],
23
7
  "fighting-style": [{ kind: "select-entity", id: "fighting-style", count: 1, entity_type: "optional-feature", where: { feature_type: "fighting_style", available_to: "self" } }]
24
8
  };
@@ -2,17 +2,28 @@ import {
2
2
  poolGrantSchema,
3
3
  selectionPoolSchema,
4
4
  tabDeclSchema
5
- } from "./chunk-4TIJKN6O.js";
5
+ } from "./chunk-23LZLBJK.js";
6
+ import {
7
+ casterTypeEnum
8
+ } from "./chunk-CJYCVNW2.js";
6
9
  import {
7
10
  featureSchema
8
- } from "./chunk-CZPMTQOY.js";
11
+ } from "./chunk-4FWNK4FD.js";
9
12
  import {
10
13
  resourceSchema
11
- } from "./chunk-PZOWBI3B.js";
14
+ } from "./chunk-YLL2QXY2.js";
12
15
  import {
13
16
  startingEquipmentEntrySchema,
14
17
  startingGoldSchema
15
- } from "./chunk-3DZ74AKK.js";
18
+ } from "./chunk-IN4M4X7P.js";
19
+ import {
20
+ choiceSchema
21
+ } from "./chunk-T26ZVCL5.js";
22
+ import {
23
+ additionalSpellsEntrySchema,
24
+ imageField,
25
+ progressionSchema
26
+ } from "./chunk-UA5KS2PL.js";
16
27
 
17
28
  // src/class/class.schema.ts
18
29
  import { z } from "zod";
@@ -67,7 +78,6 @@ var toolProficiencySchema = z.object({
67
78
  }, {
68
79
  message: "tool proficiency must declare fixed or choice"
69
80
  });
70
- var casterTypeEnum = z.enum(["full", "half", "third", "pact"]);
71
81
  var spellcastingSchema = z.object({
72
82
  caster_type: casterTypeEnum,
73
83
  ability: abilityEnum,
@@ -75,7 +85,16 @@ var spellcastingSchema = z.object({
75
85
  spell_list: z.string().min(1)
76
86
  });
77
87
  var weaponMasterySchema = z.object({
78
- starting_count: z.number().int().nonnegative(),
88
+ // §2.7's ONE deliberate relaxation, and the phase's only non-additive edit. Measured: `starting_count`
89
+ // has ZERO read sites in either repo, all 24 SRD class records are `weapon_mastery: null`, and the
90
+ // converter population is zero too (26 of 28 class docs null; both object carriers DO carry the count).
91
+ // It exists so the converter can re-emit a countless mastery object later. R4-G5 did NOT make it read: §6 takes
92
+ // the count from the class TABLE COLUMN instead (`COUNT_COLUMNS` in `pc.table-column.ts`), because the column
93
+ // is the truth on BOTH corpora, and `count.column` on the choice itself is booked to the G7 converter handoff.
94
+ // `starting_count` therefore still has ZERO read sites.
95
+ // A THREE-declaration edit (finding 11): here, `class.types.ts`, and the generator's COPIED
96
+ // `interface WeaponMasteryConfig` in tools/srd-canonical/merger-rules/class-merge.ts.
97
+ starting_count: z.number().int().nonnegative().optional(),
79
98
  scaling: z.record(z.string(), z.number().int().nonnegative()).optional()
80
99
  });
81
100
  var classTableRowSchema = z.object({
@@ -101,6 +120,10 @@ var classEntitySchema = z.object({
101
120
  count: z.number().int().positive(),
102
121
  from: z.array(skillEnum).nonempty()
103
122
  }),
123
+ // Zod strips unknown keys by default, so without this declaration an authored
124
+ // `choices:` block is silently deleted by `parseClass`. Same spelling as
125
+ // `raceEntitySchema` / `backgroundEntitySchema`.
126
+ choices: z.array(choiceSchema).optional(),
104
127
  starting_equipment: z.array(startingEquipmentEntrySchema),
105
128
  starting_gold: startingGoldSchema.optional(),
106
129
  spellcasting: spellcastingSchema.nullable(),
@@ -113,7 +136,41 @@ var classEntitySchema = z.object({
113
136
  resources: z.array(resourceSchema),
114
137
  selection_pools: z.array(selectionPoolSchema).optional(),
115
138
  pool_grants: z.array(poolGrantSchema).optional(),
116
- tabs: z.array(tabDeclSchema).optional()
139
+ tabs: z.array(tabDeclSchema).optional(),
140
+ rendering_hint: z.string().optional(),
141
+ // 28
142
+ has_fluff: z.boolean().optional(),
143
+ // 28
144
+ has_fluff_images: z.boolean().optional(),
145
+ // 27
146
+ table_col_labels: z.array(z.string().min(1)).optional(),
147
+ // 28
148
+ starting_equipment_additional_from_background: z.boolean().optional(),
149
+ // 28
150
+ multiclassing: z.unknown().optional(),
151
+ // FOUR arities measured incl. {} ×3; free-form 5etools keys
152
+ // ("thieves' tools", requirements.or[].{dex,str}) — Q1 ruling
153
+ cantrip_progression: z.array(z.number()).optional(),
154
+ // 15
155
+ prepared_spells: z.string().min(1).optional(),
156
+ // formula string "<$level$> / 2 + <$int_mod$>"
157
+ prepared_spells_change: z.string().min(1).optional(),
158
+ // "restLong"
159
+ prepared_spells_progression: z.array(z.number()).optional(),
160
+ spells_known_progression: z.array(z.number()).optional(),
161
+ spells_known_progression_fixed: z.array(z.number()).optional(),
162
+ spells_known_progression_fixed_allow_lower_level: z.boolean().optional(),
163
+ // ⚠️ BOOLEAN (finding 1)
164
+ spells_known_progression_fixed_by_level: z.record(z.string(), z.record(z.string(), z.number())).optional(),
165
+ // ⚠️ two-deep record (finding 1)
166
+ feat_progression: z.array(progressionSchema).optional(),
167
+ // 13
168
+ optionalfeature_progression: z.array(progressionSchema).optional(),
169
+ // 9 carriers; the ARRAY
170
+ // progression arm rides 4 of them
171
+ additional_spells: z.array(additionalSpellsEntrySchema).optional(),
172
+ // 7
173
+ image: imageField
117
174
  });
118
175
 
119
176
  export {
@@ -1,6 +1,6 @@
1
1
  // src/schemas/resource-schema.ts
2
2
  import { z } from "zod";
3
- var resetTriggerEnum = z.enum(["short-rest", "long-rest", "dawn", "dusk", "turn", "round", "custom"]);
3
+ var resetTriggerEnum = z.enum(["short-rest", "long-rest", "either", "dawn", "dusk", "turn", "round", "custom"]);
4
4
  var actionCostEnum = z.enum(["action", "bonus-action", "reaction", "free", "special"]);
5
5
  var resourceSchema = z.object({
6
6
  id: z.string().min(1),
@@ -25,7 +25,8 @@ var resourceSchema = z.object({
25
25
  amount: z.union([z.number(), z.string()]),
26
26
  action: actionCostEnum.optional(),
27
27
  uses: z.number().int().nonnegative().optional(),
28
- reset: resetTriggerEnum
28
+ reset: resetTriggerEnum,
29
+ restores: z.enum(["uses", "spell-slots"]).optional()
29
30
  })).optional()
30
31
  });
31
32
  var resourceConsumptionSchema = z.object({
@@ -33,12 +34,16 @@ var resourceConsumptionSchema = z.object({
33
34
  resource: z.string().optional(),
34
35
  column: z.string().optional(),
35
36
  amount: z.number().int().positive(),
37
+ amount_max: z.number().int().positive().optional(),
36
38
  expend_condition: z.enum(["roll_succeeds", "roll_fails", "target_takes_damage", "always"]).optional(),
37
39
  free_uses: z.object({
38
40
  amount: z.number().int().positive(),
39
41
  reset: resetTriggerEnum,
40
42
  state_key: z.string().optional()
41
43
  }).optional()
44
+ }).refine((c) => c.amount_max === void 0 || c.amount_max >= c.amount, {
45
+ path: ["amount_max"],
46
+ message: "amount_max must be >= amount"
42
47
  });
43
48
 
44
49
  export {
@@ -5,23 +5,31 @@ import {
5
5
  actionCostEnum,
6
6
  resetTriggerEnum,
7
7
  resourceConsumptionSchema
8
- } from "./chunk-PZOWBI3B.js";
8
+ } from "./chunk-YLL2QXY2.js";
9
9
  import {
10
10
  featureEffectSchema
11
- } from "./chunk-NXR3BD2V.js";
11
+ } from "./chunk-WPWOHGPI.js";
12
+ import {
13
+ additionalSpellsEntrySchema,
14
+ imageField,
15
+ progressionSchema
16
+ } from "./chunk-UA5KS2PL.js";
12
17
 
13
18
  // src/optional-feature/optional-feature.schema.ts
14
19
  import { z } from "zod";
15
20
  var editionEnum = z.enum(["2014", "2024"]);
16
21
  var abilityEnum = z.enum(["str", "dex", "con", "int", "wis", "cha"]);
17
22
  var wikilinkRegex = /^\[\[[^[\]]+\]\]$/;
23
+ var namedRefSchema = z.object({ name: z.string().min(1), source: z.string().min(1).optional(), visible_stats: z.boolean().optional() });
18
24
  var prerequisiteSchema = z.discriminatedUnion("kind", [
19
- z.object({ kind: z.literal("level"), min: z.number().int().positive() }),
25
+ z.object({ kind: z.literal("level"), min: z.number().int().positive(), class: namedRefSchema.optional(), subclass: namedRefSchema.optional() }),
20
26
  z.object({ kind: z.literal("spell-known"), spell: z.string().regex(wikilinkRegex) }),
21
27
  z.object({ kind: z.literal("pact"), pact: z.enum(["tome", "blade", "chain", "talisman"]) }),
22
28
  z.object({ kind: z.literal("class"), class: z.string().regex(wikilinkRegex) }),
23
29
  z.object({ kind: z.literal("ability"), ability: abilityEnum, min: z.number().int().positive() }),
24
- z.object({ kind: z.literal("other"), detail: z.string() })
30
+ z.object({ kind: z.literal("other"), detail: z.string() }),
31
+ z.object({ kind: z.literal("optionalfeature"), optionalfeature: z.string().regex(wikilinkRegex) }),
32
+ z.object({ kind: z.literal("spell-choose"), choose: z.string().min(1), entry: z.string().optional(), entry_summary: z.string().optional() })
25
33
  ]);
26
34
  var usesSchema = z.object({
27
35
  max: z.union([z.number(), z.string()]),
@@ -44,7 +52,20 @@ var optionalFeatureEntitySchema = z.object({
44
52
  passive: z.boolean().optional(),
45
53
  // Phase 3 activatable buffs: an activatable boon folds its effects only while
46
54
  // its slug is present in state.active_buffs (toggled in the PoolTab).
47
- activatable: z.boolean().optional()
55
+ activatable: z.boolean().optional(),
56
+ rendering_hint: z.string().optional(),
57
+ // the ONE root with load-bearing VALUES (88 records, G4's)
58
+ additional_spells: z.array(additionalSpellsEntrySchema).optional(),
59
+ // 54
60
+ is_class_feature_variant: z.boolean().optional(),
61
+ // 25
62
+ has_fluff_images: z.boolean().optional(),
63
+ // 2
64
+ feat_progression: z.array(progressionSchema).optional(),
65
+ // 1
66
+ optionalfeature_progression: z.array(progressionSchema).optional(),
67
+ // 1
68
+ image: imageField
48
69
  });
49
70
 
50
71
  export {
@@ -1,15 +1,18 @@
1
1
  import {
2
2
  classCodec
3
- } from "../chunk-GE4TLPWM.js";
4
- import "../chunk-42Y5IJKT.js";
5
- import "../chunk-TLYDBT5F.js";
6
- import "../chunk-4TIJKN6O.js";
7
- import "../chunk-CZPMTQOY.js";
3
+ } from "../chunk-US5IKYCW.js";
4
+ import "../chunk-5U5FFFA3.js";
5
+ import "../chunk-4U55VNC7.js";
6
+ import "../chunk-YJJTISBN.js";
7
+ import "../chunk-23LZLBJK.js";
8
+ import "../chunk-CJYCVNW2.js";
9
+ import "../chunk-4FWNK4FD.js";
8
10
  import "../chunk-WYGD2UGN.js";
9
- import "../chunk-PZOWBI3B.js";
10
- import "../chunk-3DZ74AKK.js";
11
- import "../chunk-NXSWH3AE.js";
12
- import "../chunk-NXR3BD2V.js";
11
+ import "../chunk-YLL2QXY2.js";
12
+ import "../chunk-IN4M4X7P.js";
13
+ import "../chunk-T26ZVCL5.js";
14
+ import "../chunk-WPWOHGPI.js";
15
+ import "../chunk-UA5KS2PL.js";
13
16
  export {
14
17
  classCodec
15
18
  };
@@ -1,14 +1,17 @@
1
1
  import {
2
2
  parseClass
3
- } from "../chunk-42Y5IJKT.js";
4
- import "../chunk-TLYDBT5F.js";
5
- import "../chunk-4TIJKN6O.js";
6
- import "../chunk-CZPMTQOY.js";
3
+ } from "../chunk-5U5FFFA3.js";
4
+ import "../chunk-4U55VNC7.js";
5
+ import "../chunk-YJJTISBN.js";
6
+ import "../chunk-23LZLBJK.js";
7
+ import "../chunk-CJYCVNW2.js";
8
+ import "../chunk-4FWNK4FD.js";
7
9
  import "../chunk-WYGD2UGN.js";
8
- import "../chunk-PZOWBI3B.js";
9
- import "../chunk-3DZ74AKK.js";
10
- import "../chunk-NXSWH3AE.js";
11
- import "../chunk-NXR3BD2V.js";
10
+ import "../chunk-YLL2QXY2.js";
11
+ import "../chunk-IN4M4X7P.js";
12
+ import "../chunk-T26ZVCL5.js";
13
+ import "../chunk-WPWOHGPI.js";
14
+ import "../chunk-UA5KS2PL.js";
12
15
  export {
13
16
  parseClass
14
17
  };
@@ -82,14 +82,16 @@ export declare const classEntitySchema: z.ZodObject<{
82
82
  survival: "survival";
83
83
  }>>;
84
84
  }, z.core.$strip>;
85
+ choices: z.ZodOptional<z.ZodArray<z.ZodType<import("../index.js").Choice, unknown, z.core.$ZodTypeInternals<import("../index.js").Choice, unknown>>>>;
85
86
  starting_equipment: z.ZodArray<z.ZodType<import("./class.types.js").StartingEquipmentEntry, unknown, z.core.$ZodTypeInternals<import("./class.types.js").StartingEquipmentEntry, unknown>>>;
86
87
  starting_gold: z.ZodOptional<z.ZodType<import("./class.types.js").StartingGold, unknown, z.core.$ZodTypeInternals<import("./class.types.js").StartingGold, unknown>>>;
87
88
  spellcasting: z.ZodNullable<z.ZodObject<{
88
89
  caster_type: z.ZodEnum<{
89
- pact: "pact";
90
- full: "full";
91
90
  half: "half";
91
+ full: "full";
92
+ pact: "pact";
92
93
  third: "third";
94
+ artificer: "artificer";
93
95
  }>;
94
96
  ability: z.ZodEnum<{
95
97
  str: "str";
@@ -108,7 +110,7 @@ export declare const classEntitySchema: z.ZodObject<{
108
110
  subclass_level: z.ZodNumber;
109
111
  subclass_feature_name: z.ZodString;
110
112
  weapon_mastery: z.ZodNullable<z.ZodObject<{
111
- starting_count: z.ZodNumber;
113
+ starting_count: z.ZodOptional<z.ZodNumber>;
112
114
  scaling: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodNumber>>;
113
115
  }, z.core.$strip>>;
114
116
  epic_boon_level: z.ZodNullable<z.ZodNumber>;
@@ -133,6 +135,7 @@ export declare const classEntitySchema: z.ZodObject<{
133
135
  reset: z.ZodEnum<{
134
136
  "short-rest": "short-rest";
135
137
  "long-rest": "long-rest";
138
+ either: "either";
136
139
  dawn: "dawn";
137
140
  dusk: "dusk";
138
141
  turn: "turn";
@@ -158,12 +161,17 @@ export declare const classEntitySchema: z.ZodObject<{
158
161
  reset: z.ZodEnum<{
159
162
  "short-rest": "short-rest";
160
163
  "long-rest": "long-rest";
164
+ either: "either";
161
165
  dawn: "dawn";
162
166
  dusk: "dusk";
163
167
  turn: "turn";
164
168
  round: "round";
165
169
  custom: "custom";
166
170
  }>;
171
+ restores: z.ZodOptional<z.ZodEnum<{
172
+ uses: "uses";
173
+ "spell-slots": "spell-slots";
174
+ }>>;
167
175
  }, z.core.$strip>>>;
168
176
  }, z.core.$strip>>;
169
177
  selection_pools: z.ZodOptional<z.ZodArray<z.ZodObject<{
@@ -196,7 +204,51 @@ export declare const classEntitySchema: z.ZodObject<{
196
204
  layout: z.ZodOptional<z.ZodEnum<{
197
205
  "spell-like": "spell-like";
198
206
  blocks: "blocks";
207
+ "dice-pool": "dice-pool";
208
+ "point-pool": "point-pool";
199
209
  }>>;
200
210
  }, z.core.$strip>;
201
211
  }, z.core.$strip>>>;
212
+ rendering_hint: z.ZodOptional<z.ZodString>;
213
+ has_fluff: z.ZodOptional<z.ZodBoolean>;
214
+ has_fluff_images: z.ZodOptional<z.ZodBoolean>;
215
+ table_col_labels: z.ZodOptional<z.ZodArray<z.ZodString>>;
216
+ starting_equipment_additional_from_background: z.ZodOptional<z.ZodBoolean>;
217
+ multiclassing: z.ZodOptional<z.ZodUnknown>;
218
+ cantrip_progression: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
219
+ prepared_spells: z.ZodOptional<z.ZodString>;
220
+ prepared_spells_change: z.ZodOptional<z.ZodString>;
221
+ prepared_spells_progression: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
222
+ spells_known_progression: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
223
+ spells_known_progression_fixed: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
224
+ spells_known_progression_fixed_allow_lower_level: z.ZodOptional<z.ZodBoolean>;
225
+ spells_known_progression_fixed_by_level: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodNumber>>>;
226
+ feat_progression: z.ZodOptional<z.ZodArray<z.ZodObject<{
227
+ name: z.ZodString;
228
+ progression: z.ZodUnion<readonly [z.ZodRecord<z.ZodString, z.ZodNumber>, z.ZodArray<z.ZodNumber>]>;
229
+ feature_type: z.ZodOptional<z.ZodArray<z.ZodString>>;
230
+ featureType: z.ZodOptional<z.ZodArray<z.ZodString>>;
231
+ category: z.ZodOptional<z.ZodArray<z.ZodString>>;
232
+ required: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString>>>;
233
+ }, z.core.$strip>>>;
234
+ optionalfeature_progression: z.ZodOptional<z.ZodArray<z.ZodObject<{
235
+ name: z.ZodString;
236
+ progression: z.ZodUnion<readonly [z.ZodRecord<z.ZodString, z.ZodNumber>, z.ZodArray<z.ZodNumber>]>;
237
+ feature_type: z.ZodOptional<z.ZodArray<z.ZodString>>;
238
+ featureType: z.ZodOptional<z.ZodArray<z.ZodString>>;
239
+ category: z.ZodOptional<z.ZodArray<z.ZodString>>;
240
+ required: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString>>>;
241
+ }, z.core.$strip>>>;
242
+ additional_spells: z.ZodOptional<z.ZodArray<z.ZodObject<{
243
+ name: z.ZodOptional<z.ZodString>;
244
+ ability: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
245
+ choose: z.ZodArray<z.ZodString>;
246
+ }, z.core.$strip>]>>;
247
+ known: z.ZodOptional<z.ZodUnknown>;
248
+ innate: z.ZodOptional<z.ZodUnknown>;
249
+ prepared: z.ZodOptional<z.ZodUnknown>;
250
+ expanded: z.ZodOptional<z.ZodUnknown>;
251
+ resourceName: z.ZodOptional<z.ZodString>;
252
+ }, z.core.$strip>>>;
253
+ image: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
202
254
  }, z.core.$strip>;
@@ -1,13 +1,15 @@
1
1
  import {
2
2
  classEntitySchema
3
- } from "../chunk-TLYDBT5F.js";
4
- import "../chunk-4TIJKN6O.js";
5
- import "../chunk-CZPMTQOY.js";
3
+ } from "../chunk-YJJTISBN.js";
4
+ import "../chunk-23LZLBJK.js";
5
+ import "../chunk-CJYCVNW2.js";
6
+ import "../chunk-4FWNK4FD.js";
6
7
  import "../chunk-WYGD2UGN.js";
7
- import "../chunk-PZOWBI3B.js";
8
- import "../chunk-3DZ74AKK.js";
9
- import "../chunk-NXSWH3AE.js";
10
- import "../chunk-NXR3BD2V.js";
8
+ import "../chunk-YLL2QXY2.js";
9
+ import "../chunk-IN4M4X7P.js";
10
+ import "../chunk-T26ZVCL5.js";
11
+ import "../chunk-WPWOHGPI.js";
12
+ import "../chunk-UA5KS2PL.js";
11
13
  export {
12
14
  classEntitySchema
13
15
  };
@@ -1,7 +1,8 @@
1
- import type { Feature, Ability, SkillSlug, Resource } from "@archivist-gg/dnd5e";
1
+ import type { Feature, Ability, SkillSlug, Resource, Choice } from "@archivist-gg/dnd5e";
2
2
  import type { StartingEquipmentEntry, StartingGold } from "@archivist-gg/dnd5e/types/equipment-grant";
3
3
  export type { StartingEquipmentEntry, StartingGold } from "@archivist-gg/dnd5e/types/equipment-grant";
4
4
  import type { SelectionPool, PoolGrant, TabDecl } from "@archivist-gg/dnd5e/types/selection-pool";
5
+ import type { AdditionalSpellsEntry, ProgressionEntry } from "@archivist-gg/dnd5e/schemas/entity-extras-schema";
5
6
  import type { Edition } from "@archivist-gg/dnd5e/types/edition";
6
7
  export type { Edition };
7
8
  export type ArmorCategory = "light" | "medium" | "heavy" | "shield";
@@ -30,7 +31,8 @@ export interface SkillChoices {
30
31
  count: number;
31
32
  from: SkillSlug[];
32
33
  }
33
- export type CasterType = "full" | "half" | "third" | "pact";
34
+ import type { CasterType } from "@archivist-gg/dnd5e/schemas/caster-type-schema";
35
+ export type { CasterType };
34
36
  export type SpellcastingPreparation = "known" | "prepared";
35
37
  export interface SpellcastingConfig {
36
38
  caster_type: CasterType;
@@ -38,8 +40,20 @@ export interface SpellcastingConfig {
38
40
  preparation: SpellcastingPreparation;
39
41
  spell_list: string;
40
42
  }
43
+ /** A SUBCLASS spellcasting block is a partial (R4-G1a D7): the converter emits {ability} alone on subclasses that
44
+ * only name a save ability (Path of the Giant, Four Elements) and {ability, caster_type} on the third-casters
45
+ * (Eldritch Knight, Arcane Trickster). The CLASS block stays fully required. */
46
+ export interface SubclassSpellcastingConfig {
47
+ ability: Ability;
48
+ caster_type?: CasterType;
49
+ preparation?: SpellcastingPreparation;
50
+ spell_list?: string;
51
+ }
41
52
  export interface WeaponMasteryConfig {
42
- starting_count: number;
53
+ /** OPTIONAL since R4-G1b (§2.7): the converter must be able to re-emit a countless mastery object
54
+ * (G5 owns counts-from-prose). Declaration 2 of 3 — the schema and the generator's COPIED
55
+ * `interface WeaponMasteryConfig` in tools/srd-canonical/merger-rules/class-merge.ts are the others. */
56
+ starting_count?: number;
43
57
  scaling?: Record<number, number>;
44
58
  }
45
59
  export interface ClassTableRow {
@@ -58,6 +72,14 @@ export interface ClassEntity {
58
72
  saving_throws: Ability[];
59
73
  proficiencies: ClassProficiencies;
60
74
  skill_choices: SkillChoices;
75
+ /**
76
+ * Entity-level decisions the class grants at L1, mirroring the long-standing
77
+ * `RaceEntity.choices` / `BackgroundEntity.choices` precedent. Classes were the
78
+ * sole holdout: a tool pick like the Bard's "three musical instruments of your
79
+ * choice" belongs to the CLASS, not to any one of its L1 features, so before
80
+ * this there was nowhere to author it.
81
+ */
82
+ choices?: Choice[];
61
83
  starting_equipment: StartingEquipmentEntry[];
62
84
  starting_gold?: StartingGold;
63
85
  spellcasting: SpellcastingConfig | null;
@@ -71,4 +93,27 @@ export interface ClassEntity {
71
93
  selection_pools?: SelectionPool[];
72
94
  pool_grants?: PoolGrant[];
73
95
  tabs?: TabDecl[];
96
+ /** Converter/bundle extras declared by class.schema.ts §2.7; all optional, none read today. */
97
+ rendering_hint?: string;
98
+ has_fluff?: boolean;
99
+ has_fluff_images?: boolean;
100
+ table_col_labels?: string[];
101
+ starting_equipment_additional_from_background?: boolean;
102
+ /** RAW 5etools passthrough (four measured arities incl. `{}`): `unknown` mirrors `z.unknown()`. */
103
+ multiclassing?: unknown;
104
+ cantrip_progression?: number[];
105
+ prepared_spells?: string;
106
+ prepared_spells_change?: string;
107
+ prepared_spells_progression?: number[];
108
+ spells_known_progression?: number[];
109
+ spells_known_progression_fixed?: number[];
110
+ /** ⚠️ BOOLEAN, not an array (finding 1). */
111
+ spells_known_progression_fixed_allow_lower_level?: boolean;
112
+ /** ⚠️ TWO-DEEP record: level -> spell level -> count (finding 1). */
113
+ spells_known_progression_fixed_by_level?: Record<string, Record<string, number>>;
114
+ feat_progression?: ProgressionEntry[];
115
+ optionalfeature_progression?: ProgressionEntry[];
116
+ additional_spells?: AdditionalSpellsEntry[];
117
+ /** One wikilink, or an array of them for the multi-fluff-image emit. */
118
+ image?: string | string[];
74
119
  }
@@ -0,0 +1,9 @@
1
+ import type { DocCodec } from "@archivist-gg/core";
2
+ import type { ConditionEntity } from "./condition.types.js";
3
+ /**
4
+ * Normalizing codec. `parse` delegates to `parseCondition`, which seeds the
5
+ * `edition: "2014"` default and validates against `conditionEntitySchema`.
6
+ * `serialize` stays `yaml.dump` (the edit-save path uses obsidian's separate
7
+ * serializer), mirroring every sibling entity codec.
8
+ */
9
+ export declare const conditionCodec: DocCodec<ConditionEntity>;
@@ -0,0 +1,2 @@
1
+ import type { EntityType } from "@archivist-gg/core";
2
+ export declare const conditionEntityType: EntityType;
@@ -0,0 +1,13 @@
1
+ import type { ConditionEntity } from "./condition.types.js";
2
+ import { ParseResult } from "@archivist-gg/core";
3
+ /**
4
+ * The RACE pattern (spec §6): required keys enforced by `parseYaml`, the
5
+ * `edition: "2014"` default seeded BEFORE validation (a declared edition wins —
6
+ * the spread order is load-bearing), and `result.data` returned DIRECTLY. That
7
+ * keeps `slug` on the output — the spell parser's slug strip is what mints its
8
+ * 1,048-row census row — and, because the measured corpus carries exactly the two
9
+ * declared key-sets, `z.object`'s strip removes nothing. The absence of a
10
+ * KNOWN_KEYS gate and a `raw` bag is why there is no *relocated* or *duplicated*
11
+ * row either.
12
+ */
13
+ export declare function parseCondition(source: string): ParseResult<ConditionEntity>;
@@ -0,0 +1,7 @@
1
+ import {
2
+ parseCondition
3
+ } from "../chunk-6X2NV665.js";
4
+ import "../chunk-UA5KS2PL.js";
5
+ export {
6
+ parseCondition
7
+ };
@@ -0,0 +1,29 @@
1
+ import { z } from "zod";
2
+ /**
3
+ * The `condition` entity (spec §6). Measured corpus at design time: 89 documents
4
+ * (59 converter over 4 books + 30 bundle) in exactly TWO key-sets — with
5
+ * `has_fluff_images` (39) and without (50) — over 15 distinct names that are
6
+ * BYTE-IDENTICAL across every book that ships them. Editions: converter 44/15,
7
+ * bundle 15/15, so the closed enum is safe. NOT every book ships all 15
8
+ * (`Hunt for the Thessalhydra` has no Exhaustion): completeness is never assumed.
9
+ *
10
+ * Plain `z.object` on purpose — no `.loose()`, no raw bag, no KNOWN_KEYS list: the
11
+ * corpus has no keys beyond these, and the parser returns the validated object
12
+ * directly (see `condition.parser.ts`), so nothing is relocated or duplicated.
13
+ *
14
+ * `edition` is REQUIRED here; the parser seeds `"2014"` BEFORE validation, so an
15
+ * authored note without the key still parses (all 89 corpus docs carry it).
16
+ * `image` is already `.optional()` at its source — never append a second one.
17
+ */
18
+ export declare const conditionEntitySchema: z.ZodObject<{
19
+ slug: z.ZodString;
20
+ name: z.ZodString;
21
+ edition: z.ZodEnum<{
22
+ 2014: "2014";
23
+ 2024: "2024";
24
+ }>;
25
+ source: z.ZodString;
26
+ description: z.ZodString;
27
+ has_fluff_images: z.ZodOptional<z.ZodBoolean>;
28
+ image: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
29
+ }, z.core.$strip>;
@@ -0,0 +1,15 @@
1
+ import type { imageField } from "../schemas/entity-extras-schema.js";
2
+ import type { Edition } from "../types/edition.js";
3
+ import type { z } from "zod";
4
+ /** A 5e condition document (spec §6). Mirrors `conditionEntitySchema` exactly. */
5
+ export interface ConditionEntity {
6
+ slug: string;
7
+ name: string;
8
+ edition: Edition;
9
+ source: string;
10
+ /** Markdown; wikilinks to sibling conditions ride through verbatim. */
11
+ description: string;
12
+ has_fluff_images?: boolean;
13
+ /** One wikilink, or an array for >= 2 fluff images (images-ON emit). */
14
+ image?: z.infer<typeof imageField>;
15
+ }
File without changes