@optolith/entity-descriptions 0.4.21 → 0.4.23

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 CHANGED
@@ -2,6 +2,22 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) for commit guidelines.
4
4
 
5
+ ## [0.4.23](https://github.com/Optolith/entity-descriptions/compare/v0.4.22...v0.4.23) (2026-06-20)
6
+
7
+
8
+ ### Features
9
+
10
+ * apply publication options to enhancements ([b4ba358](https://github.com/Optolith/entity-descriptions/commit/b4ba3583b4a7d7c989fc7b1e81d463ded6a50c54))
11
+ * apply publication options to whole entity description ([344c91f](https://github.com/Optolith/entity-descriptions/commit/344c91f2ba54af021d897540d9f074c674cbe0e2))
12
+ * publication options ([5cc4ce1](https://github.com/Optolith/entity-descriptions/commit/5cc4ce1e0a0df96747b162f8010a41d482f199f9))
13
+
14
+ ## [0.4.22](https://github.com/Optolith/entity-descriptions/compare/v0.4.21...v0.4.22) (2026-06-14)
15
+
16
+
17
+ ### Features
18
+
19
+ * blessing traditions ([b0bbf2d](https://github.com/Optolith/entity-descriptions/commit/b0bbf2dadc483b14e059a0f870dd8c5477f53831))
20
+
5
21
  ## [0.4.21](https://github.com/Optolith/entity-descriptions/compare/v0.4.20...v0.4.21) (2026-06-14)
6
22
 
7
23
  ## [0.4.20](https://github.com/Optolith/entity-descriptions/compare/v0.4.19...v0.4.20) (2026-06-13)
package/lib/creator.d.ts CHANGED
@@ -2,6 +2,7 @@ import type { EntityMap } from "@optolith/database-schema/gen";
2
2
  import type { GetInstanceById } from "./helpers/getTypes.js";
3
3
  import type { LocaleEnvironment } from "./helpers/locale.js";
4
4
  import type { EntityDescription, RawEntityDescription } from "./index.js";
5
+ import { type PublicationOptions } from "./references/publicationOptions.js";
5
6
  /**
6
7
  * A union type of entities with their names as a discriminant property.
7
8
  */
@@ -29,4 +30,6 @@ export type EntityDescriptionCreator<ES extends keyof EntityMap = keyof EntityMa
29
30
  getInstanceById: GetInstanceById<"Publication">;
30
31
  } = {
31
32
  getInstanceById: GetInstanceById<"Publication">;
32
- }, R = EntityDescription> = (databaseAccessors: A, locale: LocaleEnvironment, entry: TaggedEntity<ES>) => R | undefined;
33
+ }, R = EntityDescription> = (databaseAccessors: A, locale: LocaleEnvironment, entry: TaggedEntity<ES>, options: {
34
+ publications: PublicationOptions;
35
+ }) => R | undefined;
package/lib/creator.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { isNotNullish } from "@elyukai/utils/nullable";
2
2
  import { assertExhaustive } from "@elyukai/utils/typeSafety";
3
3
  import { getReferencesTranslation } from "./references/index.js";
4
+ import { isEntryFromIncludedPublication, } from "./references/publicationOptions.js";
4
5
  const mapRawSectionContent = (mapDefinitionList, section) => {
5
6
  switch (section.type) {
6
7
  case "plain":
@@ -53,9 +54,10 @@ const mapRawSection = (section) => {
53
54
  * Creates a function that creates the JSON representation of the rules text for
54
55
  * a library entry.
55
56
  */
56
- export const createEntityDescriptionCreator = (fn) => (databaseAccessors, locale, entry) => {
57
- const rawEntry = fn(databaseAccessors, locale, entry);
58
- if (rawEntry === undefined) {
57
+ export const createEntityDescriptionCreator = (fn) => (databaseAccessors, locale, entry, options) => {
58
+ const rawEntry = fn(databaseAccessors, locale, entry, options);
59
+ if (rawEntry === undefined ||
60
+ !isEntryFromIncludedPublication({ src: rawEntry.references }, databaseAccessors.getInstanceById, locale.translateMap, options.publications)) {
59
61
  return undefined;
60
62
  }
61
63
  return {
@@ -67,6 +69,6 @@ export const createEntityDescriptionCreator = (fn) => (databaseAccessors, locale
67
69
  })),
68
70
  references: rawEntry.references === undefined
69
71
  ? undefined
70
- : getReferencesTranslation(databaseAccessors.getInstanceById, locale, rawEntry.references),
72
+ : getReferencesTranslation(databaseAccessors.getInstanceById, options.publications, locale, rawEntry.references),
71
73
  };
72
74
  };
@@ -46,7 +46,7 @@ export type BaseActivatableTranslation = {
46
46
  /**
47
47
  * Get a JSON representation of the rules text for a special ability.
48
48
  */
49
- export declare const getActivatableEntityDescription: import("../creator.js").EntityDescriptionCreator<"Advantage" | "Disadvantage" | "AdvancedCombatSpecialAbility" | "AdvancedKarmaSpecialAbility" | "AdvancedMagicalSpecialAbility" | "AdvancedSkillSpecialAbility" | "AncestorGlyph" | "ArcaneOrbEnchantment" | "AttireEnchantment" | "Beutelzauber" | "BlessedTradition" | "BowlEnchantment" | "BrawlingSpecialAbility" | "CauldronEnchantment" | "CeremonialItemSpecialAbility" | "ChronicleEnchantment" | "CombatSpecialAbility" | "CombatStyleSpecialAbility" | "CommandSpecialAbility" | "DaggerRitual" | "FamiliarSpecialAbility" | "FatePointSexSpecialAbility" | "FatePointSpecialAbility" | "FoolsHatEnchantment" | "GeneralSpecialAbility" | "Haubenzauber" | "InstrumentEnchantment" | "KarmaSpecialAbility" | "Krallenkettenzauber" | "Kristallkugelzauber" | "LiturgicalStyleSpecialAbility" | "LycantropicGift" | "MagicalSign" | "MagicalSpecialAbility" | "MagicalTradition" | "MagicStyleSpecialAbility" | "OrbEnchantment" | "PactGift" | "ProtectiveWardingCircleSpecialAbility" | "RingEnchantment" | "Sermon" | "SexSpecialAbility" | "SickleRitual" | "SikaryanDrainSpecialAbility" | "SkillStyleSpecialAbility" | "SpellSwordEnchantment" | "StaffEnchantment" | "ToyEnchantment" | "Trinkhornzauber" | "VampiricGift" | "Vision" | "WandEnchantment" | "WeaponEnchantment", {
49
+ export declare const getActivatableEntityDescription: import("../creator.js").EntityDescriptionCreator<"Advantage" | "Disadvantage" | "AdvancedCombatSpecialAbility" | "AdvancedKarmaSpecialAbility" | "AdvancedMagicalSpecialAbility" | "AdvancedSkillSpecialAbility" | "AncestorGlyph" | "ArcaneOrbEnchantment" | "AttireEnchantment" | "Beutelzauber" | "BlessedTradition" | "BowlEnchantment" | "BrawlingSpecialAbility" | "CauldronEnchantment" | "CeremonialItemSpecialAbility" | "ChronicleEnchantment" | "CombatSpecialAbility" | "CombatStyleSpecialAbility" | "CommandSpecialAbility" | "DaggerRitual" | "FamiliarSpecialAbility" | "FatePointSexSpecialAbility" | "FatePointSpecialAbility" | "FoolsHatEnchantment" | "GeneralSpecialAbility" | "Haubenzauber" | "Hauerkettenzauber" | "InstrumentEnchantment" | "KarmaSpecialAbility" | "Keulenzauber" | "Krallenkettenzauber" | "Kristallkugelzauber" | "LiturgicalStyleSpecialAbility" | "LycantropicGift" | "MagicalSign" | "MagicalSpecialAbility" | "MagicalTradition" | "MagicStyleSpecialAbility" | "OrbEnchantment" | "PactGift" | "ProtectiveWardingCircleSpecialAbility" | "RingEnchantment" | "Schweinetrommelzauber" | "Sermon" | "SexSpecialAbility" | "SickleRitual" | "SikaryanDrainSpecialAbility" | "SkillStyleSpecialAbility" | "SpellSwordEnchantment" | "StaffEnchantment" | "ToyEnchantment" | "Trinkhornzauber" | "VampiricGift" | "Vision" | "WandEnchantment" | "WeaponEnchantment", {
50
50
  getInstanceById: GetInstanceById<"Publication" | "Subject" | ActivatableIdentifier["kind"] | RatedIdentifier["kind"] | "TradeSecret" | "Aspect" | "Property" | "Race" | "Culture" | "State" | "Enhancement" | "PactCategory" | "PactDomain" | "SocialStatus" | "Weapon" | "Patron" | "PersonalityTrait">;
51
51
  getAllInstances: GetAllInstances<"Script">;
52
52
  getResolvedSelectOptionById: GetResolvedSelectOptionById;
@@ -1,11 +1,12 @@
1
1
  import { type RatedIdentifier } from "@optolith/database-schema/gen";
2
- import type { GetAllChildInstancesForParent, GetInstanceById } from "../helpers/getTypes.js";
2
+ import type { GetAllChildInstancesForParent, GetAllInstances, GetInstanceById } from "../helpers/getTypes.js";
3
3
  import type { IdMap } from "../index.js";
4
4
  /**
5
5
  * Get a JSON representation of the rules text for a blessing.
6
6
  */
7
7
  export declare const getBlessingEntityDescription: import("../creator.js").EntityDescriptionCreator<"Blessing", {
8
8
  getInstanceById: GetInstanceById<"Publication" | "TargetCategory">;
9
+ getAllInstances: GetAllInstances<"BlessedTradition">;
9
10
  }, import("../index.js").EntityDescription>;
10
11
  /**
11
12
  * Get a JSON representation of the rules text for a liturgical chant.
@@ -13,6 +13,47 @@ import { renderTargetCategory } from "./partial/rated/activatable/targetCategory
13
13
  import { renderImprovementCost } from "./partial/rated/improvementCost.js";
14
14
  import { renderSkillCheckWithPenalty } from "./partial/rated/skillCheck.js";
15
15
  import { ResponsiveTextSize } from "./partial/responsiveText.js";
16
+ const getTextForBlessingTraditions = (deps, id) => {
17
+ const blessedTraditions = deps.getAllInstances("BlessedTradition");
18
+ const primaryTradition = blessedTraditions.find(trad => trad.content.primaryBlessing === id);
19
+ const secondaryTraditions = blessedTraditions.filter(trad => {
20
+ switch (trad.content.restricted_blessings?.kind) {
21
+ case "Six":
22
+ return !trad.content.restricted_blessings.Six.includes(id);
23
+ case "Three":
24
+ return !trad.content.restricted_blessings.Three.includes(id);
25
+ case undefined:
26
+ return false;
27
+ default:
28
+ return assertExhaustive(trad.content.restricted_blessings);
29
+ }
30
+ });
31
+ const translateTradition = (trad) => {
32
+ const traditionTranslation = deps.translateMap(trad.content.translations);
33
+ const name = traditionTranslation?.name_compressed ?? traditionTranslation?.name;
34
+ if (name === undefined) {
35
+ return undefined;
36
+ }
37
+ return attributedInstance(name, "BlessedTradition", trad.id, {
38
+ context: '"traditions"',
39
+ });
40
+ };
41
+ const secondaryTraditionTexts = secondaryTraditions
42
+ .map(translateTradition)
43
+ .filter(isNotNullish)
44
+ .sort(deps.localeCompare);
45
+ const text = [
46
+ deps.translate("General"),
47
+ primaryTradition ? translateTradition(primaryTradition) : undefined,
48
+ ...secondaryTraditionTexts,
49
+ ]
50
+ .filter(isNotNullish)
51
+ .join(", ");
52
+ return {
53
+ label: deps.translate("Traditions"),
54
+ value: text,
55
+ };
56
+ };
16
57
  const getTextForTraditions = (deps, values) => {
17
58
  const getAspectName = (aspectId) => attributedName(deps.translateMap, deps.getInstanceById, "traditions", "Aspect", aspectId);
18
59
  const text = values
@@ -36,7 +77,7 @@ const getTextForTraditions = (deps, values) => {
36
77
  if (aspects.length === 0) {
37
78
  return attributedStringName;
38
79
  }
39
- return `${attributedStringName} (${aspects.join(" and ")})`;
80
+ return `${attributedStringName} (${deps.localeJoin(aspects, "conjunction")})`;
40
81
  }
41
82
  default:
42
83
  return assertExhaustive(trad);
@@ -52,7 +93,7 @@ const getTextForTraditions = (deps, values) => {
52
93
  /**
53
94
  * Get a JSON representation of the rules text for a blessing.
54
95
  */
55
- export const getBlessingEntityDescription = createEntityDescriptionCreator(({ getInstanceById }, locale, { content: entry }) => {
96
+ export const getBlessingEntityDescription = createEntityDescriptionCreator(({ getInstanceById, getAllInstances }, locale, { id, content: entry }) => {
56
97
  const { translate, translateMap } = locale;
57
98
  const translation = translateMap(entry.translations);
58
99
  if (translation === undefined) {
@@ -61,7 +102,9 @@ export const getBlessingEntityDescription = createEntityDescriptionCreator(({ ge
61
102
  const env = {
62
103
  translate,
63
104
  translateMap,
105
+ localeCompare: locale.compare,
64
106
  getInstanceById,
107
+ getAllInstances,
65
108
  responsiveTextSize: ResponsiveTextSize.Full,
66
109
  };
67
110
  const range = renderNonModifiableRange(entry.parameters.range, false).run(env);
@@ -80,6 +123,7 @@ export const getBlessingEntityDescription = createEntityDescriptionCreator(({ ge
80
123
  combineGeneratedTextWithStaticTranslation(translate("Range"), range, translation.range),
81
124
  combineGeneratedTextWithStaticTranslation(translate("Duration"), duration, translation.duration),
82
125
  renderTargetCategory(entry.target).run(env),
126
+ getTextForBlessingTraditions(env, id),
83
127
  ],
84
128
  },
85
129
  ],
@@ -90,8 +134,8 @@ export const getBlessingEntityDescription = createEntityDescriptionCreator(({ ge
90
134
  /**
91
135
  * Get a JSON representation of the rules text for a liturgical chant.
92
136
  */
93
- export const getLiturgicalChantEntityDescription = createEntityDescriptionCreator(({ getInstanceById, getChildInstancesForInstanceId, idMap }, locale, { content: entry, entity, id }) => {
94
- const { translate, translateMap, compare: localeCompare } = locale;
137
+ export const getLiturgicalChantEntityDescription = createEntityDescriptionCreator(({ getInstanceById, getChildInstancesForInstanceId, idMap }, locale, { content: entry, entity, id }, options) => {
138
+ const { translate, translateMap, compare: localeCompare, join: localeJoin } = locale;
95
139
  const translation = translateMap(entry.translations);
96
140
  if (translation === undefined) {
97
141
  return undefined;
@@ -117,6 +161,7 @@ export const getLiturgicalChantEntityDescription = createEntityDescriptionCreato
117
161
  return assertExhaustive(param);
118
162
  }
119
163
  },
164
+ publicationOptions: options.publications,
120
165
  };
121
166
  const { castingTime, cost, range, duration } = renderFastPerformanceParameters(entry.parameters).run(env);
122
167
  return {
@@ -137,6 +182,7 @@ export const getLiturgicalChantEntityDescription = createEntityDescriptionCreato
137
182
  translate,
138
183
  translateMap,
139
184
  localeCompare,
185
+ localeJoin,
140
186
  getInstanceById,
141
187
  }, entry.traditions),
142
188
  renderImprovementCost(entry.improvement_cost).run(env),
@@ -151,8 +197,8 @@ export const getLiturgicalChantEntityDescription = createEntityDescriptionCreato
151
197
  /**
152
198
  * Get a JSON representation of the rules text for a ceremony.
153
199
  */
154
- export const getCeremonyEntityDescription = createEntityDescriptionCreator(({ getInstanceById, getChildInstancesForInstanceId, idMap }, locale, { content: entry, entity, id }) => {
155
- const { translate, translateMap, compare: localeCompare } = locale;
200
+ export const getCeremonyEntityDescription = createEntityDescriptionCreator(({ getInstanceById, getChildInstancesForInstanceId, idMap }, locale, { content: entry, entity, id }, options) => {
201
+ const { translate, translateMap, compare: localeCompare, join: localeJoin } = locale;
156
202
  const translation = translateMap(entry.translations);
157
203
  if (translation === undefined) {
158
204
  return undefined;
@@ -178,6 +224,7 @@ export const getCeremonyEntityDescription = createEntityDescriptionCreator(({ ge
178
224
  return assertExhaustive(param);
179
225
  }
180
226
  },
227
+ publicationOptions: options.publications,
181
228
  };
182
229
  const { castingTime, cost, range, duration } = renderSlowPerformanceParameters(entry.parameters).run(env);
183
230
  return {
@@ -198,6 +245,7 @@ export const getCeremonyEntityDescription = createEntityDescriptionCreator(({ ge
198
245
  translate,
199
246
  translateMap,
200
247
  localeCompare,
248
+ localeJoin,
201
249
  getInstanceById,
202
250
  }, entry.traditions),
203
251
  renderImprovementCost(entry.improvement_cost).run(env),
@@ -4,4 +4,4 @@ import { type StdReader } from "./reader.js";
4
4
  /**
5
5
  * Render the enhancements section for an entity description, if applicable.
6
6
  */
7
- export declare const renderEnhancements: (parentId: SkillWithEnhancementsIdentifier, parentImprovementCost: ImprovementCost) => StdReader<RawEntityDescriptionSection | undefined, "t" | "tm" | "lc" | "lj" | "ibi" | "acibp", RatedIdentifier["kind"] | "Enhancement", "Enhancement">;
7
+ export declare const renderEnhancements: (parentId: SkillWithEnhancementsIdentifier, parentImprovementCost: ImprovementCost) => StdReader<RawEntityDescriptionSection | undefined, "t" | "tm" | "lc" | "lj" | "ibi" | "acibp" | "po", RatedIdentifier["kind"] | "Enhancement" | "Publication", "Enhancement">;
@@ -4,6 +4,7 @@ import { compareNumber } from "@elyukai/utils/ordering";
4
4
  import { Reader } from "@elyukai/utils/reader";
5
5
  import { assertExhaustive } from "@elyukai/utils/typeSafety";
6
6
  import { getAdventurePointsForActivation } from "@optolith/adventure-points/improvement-cost";
7
+ import { filterIncludedPublicationEntriesMapR } from "../../references/publicationOptions.js";
7
8
  import { printEnhancementPrerequisites } from "./prerequisites/index.js";
8
9
  import { getChildInstancesForInstanceIdR, translateMapR, translateR, } from "./reader.js";
9
10
  const getEnhancementAPValue = (adventurePoints, parentImprovementCost) => {
@@ -23,7 +24,9 @@ const renderEnhancement = (enhancement, parentImprovementCost) => translateMapR(
23
24
  /**
24
25
  * Render the enhancements section for an entity description, if applicable.
25
26
  */
26
- export const renderEnhancements = (parentId, parentImprovementCost) => getChildInstancesForInstanceIdR("Enhancement", parentId).thenW(enhancements => Reader.traverse(enhancements.toSorted(on(e => e.content.skill_rating, compareNumber)), enhancement => renderEnhancement(enhancement, parentImprovementCost)).thenW(enhancementDescriptions => {
27
+ export const renderEnhancements = (parentId, parentImprovementCost) => getChildInstancesForInstanceIdR("Enhancement", parentId).thenW(enhancements => filterIncludedPublicationEntriesMapR(enhancements, e => e.content)
28
+ .thenW(filteredEnhancements => Reader.traverse(filteredEnhancements.toSorted(on(e => e.content.skill_rating, compareNumber)), enhancement => renderEnhancement(enhancement, parentImprovementCost)))
29
+ .thenW(enhancementDescriptions => {
27
30
  const nonNullishDescriptions = enhancementDescriptions.filter(isNotNullish);
28
31
  if (nonNullishDescriptions.length === 0) {
29
32
  return Reader.of(undefined);
@@ -57,7 +57,7 @@ export declare const renderNonModifiableSustainedCost: (value: NonModifiableSust
57
57
  } & {
58
58
  translate: Translate;
59
59
  responsiveTextSize: ResponsiveTextSize;
60
- } & StdEnv<"t" | "rts" | "tm" | "eu", never, never, never>, string>;
60
+ } & StdEnv<"tm" | "t" | "rts" | "eu", never, never, never>, string>;
61
61
  /**
62
62
  * Returns the text for the cost of a sustained activatable skill.
63
63
  */
@@ -4,6 +4,7 @@ import type { IdArgsVariant } from "tsondb/schema/gen";
4
4
  import type { GetAllChildInstancesForParent, GetAllInstances, GetInstanceById } from "../../helpers/getTypes.js";
5
5
  import type { FormatNumber, LocaleCompare, LocaleJoin, LocaleJoinType } from "../../helpers/locale.js";
6
6
  import type { Format, LocaleMap, Translate, TranslateMap, TranslationKeyMatchingParamsOfKey, TranslationKeysWithoutParams, TranslationParamsInArray, Translations } from "../../helpers/translate.js";
7
+ import type { PublicationOptions } from "../../references/publicationOptions.js";
7
8
  import type { GetResolvedSelectOptionById } from "./prerequisites/single/activatable.js";
8
9
  import type { ModifiableParameter } from "./rated/activatable/nonModifiableSuffix.js";
9
10
  import { Speed } from "./rated/activatable/speed.js";
@@ -27,6 +28,7 @@ export type EnvMap<E extends keyof EntityMap = never, AE extends keyof EntityMap
27
28
  getAllInstances: GetAllInstances<AE>;
28
29
  getChildInstancesForInstanceId: GetAllChildInstancesForParent<CE>;
29
30
  getResolvedSelectOptionById: GetResolvedSelectOptionById;
31
+ publicationOptions: PublicationOptions;
30
32
  };
31
33
  /**
32
34
  * Shortcuts for selecting keys of the shared environment map type.
@@ -46,6 +48,7 @@ export type EnvMapAbbr = {
46
48
  ai: "getAllInstances";
47
49
  acibp: "getChildInstancesForInstanceId";
48
50
  rso: "getResolvedSelectOptionById";
51
+ po: "publicationOptions";
49
52
  };
50
53
  /**
51
54
  * The standard set of environment properties for readers in this project.
@@ -40,4 +40,4 @@ export declare const replaceTextIfNeeded: (translations: LocaleMap<{
40
40
  */
41
41
  export declare const appendNoteIfNeeded: (translations: LocaleMap<{
42
42
  note?: ResponsiveTextOptional;
43
- }> | undefined, valueToAppendTo: string) => Reader<StdEnv<"rts" | "tm">, string>;
43
+ }> | undefined, valueToAppendTo: string) => Reader<StdEnv<"tm" | "rts">, string>;
@@ -5,7 +5,7 @@ import { type ResponsiveTextSize } from "../responsiveText.js";
5
5
  /**
6
6
  * Possible units to use for time spans.
7
7
  */
8
- export type TimeSpanUnit = "Seconds" | "Minutes" | "Hours" | "Days" | "Weeks" | "Months" | "Years" | "Centuries" | "Actions" | "CombatRounds" | "SeductionActions" | "Rounds";
8
+ export type TimeSpanUnit = "Seconds" | "Minutes" | "Hours" | "Days" | "Weeks" | "Months" | "Years" | "Decades" | "Centuries" | "Actions" | "CombatRounds" | "SeductionActions" | "Rounds";
9
9
  /**
10
10
  * Returns the text for a time span unit.
11
11
  */
@@ -9,6 +9,7 @@ const timeSpanUnitTranslationKeys = {
9
9
  Weeks: [".input {$value :number} .input {$style :string} {{{$value} weeks}}", "{$value} weeks", ".input {$value :number} .input {$style :string} {{{$value} wks.}}", "{$value} wks."],
10
10
  Months: [".input {$value :number} .input {$style :string} {{{$value} months}}", "{$value} months", ".input {$value :number} .input {$style :string} {{{$value} mos.}}", "{$value} mos."],
11
11
  Years: [".input {$value :number} .input {$style :string} {{{$value} years}}", "{$value} years", ".input {$value :number} .input {$style :string} {{{$value} yrs.}}", "{$value} yrs."],
12
+ Decades: [".input {$value :number} .input {$style :string} {{{$value} decades}}", "{$value} decades", ".input {$value :number} .input {$style :string} {{{$value} dcs.}}", "{$value} dcs."],
12
13
  Centuries: [".input {$value :number} .input {$style :string} {{{$value} centuries}}", "{$value} centuries", ".input {$value :number} .input {$style :string} {{{$value} cent.}}", "{$value} cent."],
13
14
  Actions: [".input {$value :number} .input {$style :string} {{{$value} actions}}", "{$value} actions", ".input {$value :number} .input {$style :string} {{{$value} act}}", "{$value} act"],
14
15
  CombatRounds: [".input {$value :number} .input {$style :string} {{{$value} combat rounds}}", "{$value} combat rounds", ".input {$value :number} .input {$style :string} {{{$value} CR}}", "{$value} CR"],
@@ -127,7 +127,7 @@ export const getCantripEntityDescription = createEntityDescriptionCreator(({ get
127
127
  /**
128
128
  * Get a JSON representation of the rules text for a skill.
129
129
  */
130
- export const getSpellEntityDescription = createEntityDescriptionCreator(({ getInstanceById, getChildInstancesForInstanceId, idMap }, locale, { content: entry, entity, id }) => {
130
+ export const getSpellEntityDescription = createEntityDescriptionCreator(({ getInstanceById, getChildInstancesForInstanceId, idMap }, locale, { content: entry, entity, id }, options) => {
131
131
  const { translate, translateMap, compare: localeCompare } = locale;
132
132
  const translation = translateMap(entry.translations);
133
133
  if (translation === undefined) {
@@ -154,6 +154,7 @@ export const getSpellEntityDescription = createEntityDescriptionCreator(({ getIn
154
154
  return assertExhaustive(param);
155
155
  }
156
156
  },
157
+ publicationOptions: options.publications,
157
158
  };
158
159
  const { castingTime, cost, range, duration } = renderFastPerformanceParameters(entry.parameters).run(env);
159
160
  return {
@@ -184,7 +185,7 @@ export const getSpellEntityDescription = createEntityDescriptionCreator(({ getIn
184
185
  /**
185
186
  * Get a JSON representation of the rules text for a ritual.
186
187
  */
187
- export const getRitualEntityDescription = createEntityDescriptionCreator(({ getInstanceById, getChildInstancesForInstanceId, idMap }, locale, { content: entry, entity, id }) => {
188
+ export const getRitualEntityDescription = createEntityDescriptionCreator(({ getInstanceById, getChildInstancesForInstanceId, idMap }, locale, { content: entry, entity, id }, options) => {
188
189
  const { translate, translateMap, compare: localeCompare } = locale;
189
190
  const translation = translateMap(entry.translations);
190
191
  if (translation === undefined) {
@@ -211,6 +212,7 @@ export const getRitualEntityDescription = createEntityDescriptionCreator(({ getI
211
212
  return assertExhaustive(param);
212
213
  }
213
214
  },
215
+ publicationOptions: options.publications,
214
216
  };
215
217
  const { castingTime, cost, range, duration } = renderSlowPerformanceParameters(entry.parameters).run(env);
216
218
  return {