@optolith/database-schema 0.107.1 → 0.108.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,27 @@
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.108.1](https://github.com/Optolith/database-schema/compare/v0.108.0...v0.108.1) (2026-10-17)
6
+
7
+ ### Bug Fixes
8
+
9
+ * property specialization translation name ([4049f08](https://github.com/Optolith/database-schema/commit/4049f0841e53da33e83f92d541d54093f1514914))
10
+
11
+ ## [0.108.0](https://github.com/Optolith/database-schema/compare/v0.107.1...v0.108.0) (2026-10-17)
12
+
13
+ ### ⚠ BREAKING CHANGES
14
+
15
+ * gems with associated properties and optional color
16
+
17
+ ### Features
18
+
19
+ * gems with associated properties and optional color ([48a4a5e](https://github.com/Optolith/database-schema/commit/48a4a5eea0cc07336bb49aef02f5e9118664a34e))
20
+ * property specializations ([83b38df](https://github.com/Optolith/database-schema/commit/83b38df2f64a61c63062dca23d127080605ae9a0))
21
+
22
+ ### Bug Fixes
23
+
24
+ * **cache:** talisman trade secret prerequisites include associated tradition ([9935e24](https://github.com/Optolith/database-schema/commit/9935e24fbf4788a84b27a5f115f74d0d6a6990e0))
25
+
5
26
  ## [0.107.1](https://github.com/Optolith/database-schema/compare/v0.107.0...v0.107.1) (2026-10-16)
6
27
 
7
28
  ### Features
package/gen/types.d.ts CHANGED
@@ -145,6 +145,7 @@ export type EntityMap = {
145
145
  ProfessionVariant: ProfessionVariant
146
146
  ProfessionVersion: ProfessionVersion
147
147
  Property: Property
148
+ PropertySpecialization: PropertySpecialization
148
149
  ProtectiveWardingCircleSpecialAbility: ProtectiveWardingCircleSpecialAbility
149
150
  Publication: Publication
150
151
  Race: Race
@@ -217,6 +218,7 @@ export type ChildEntityMap = {
217
218
  ProfessionPackage: [ProfessionPackage, "profession_version", ProfessionPackage["profession_version"]]
218
219
  ProfessionVariant: [ProfessionVariant, "profession_package", ProfessionVariant["profession_package"]]
219
220
  ProfessionVersion: [ProfessionVersion, "profession", ProfessionVersion["profession"]]
221
+ PropertySpecialization: [PropertySpecialization, "parent", PropertySpecialization["parent"]]
220
222
  RaceVariant: [RaceVariant, "race", RaceVariant["race"]]
221
223
  SkillApplication: [SkillApplication, "parent", SkillApplication["parent"]]
222
224
  SkillUse: [SkillUse, "parent", SkillUse["parent"]]
@@ -247,6 +249,7 @@ export type EnumMap = {
247
249
  AnimistPowerImprovementCost: AnimistPowerImprovementCost
248
250
  AnimistPowerPerformanceParameters: AnimistPowerPerformanceParameters
249
251
  AnimistPowerPrerequisiteGroup: AnimistPowerPrerequisiteGroup
252
+ AnyPropertySpecializationIdentifier: AnyPropertySpecializationIdentifier
250
253
  ApplicableAmmunitionCategory: ApplicableAmmunitionCategory
251
254
  ApplicableArmorCategory: ApplicableArmorCategory
252
255
  ApplicableCombatTechniques: ApplicableCombatTechniques
@@ -321,6 +324,7 @@ export type EnumMap = {
321
324
  DerivedCharacteristicPrimaryAttributeValue: DerivedCharacteristicPrimaryAttributeValue
322
325
  DerivedCharacteristicSkillCheckPenalty: DerivedCharacteristicSkillCheckPenalty
323
326
  DerivedCharacteristicType: DerivedCharacteristicType
327
+ DerivedPropertySpecializations: DerivedPropertySpecializations
324
328
  DisplayOption: DisplayOption
325
329
  DominationRitualDuration: DominationRitualDuration
326
330
  DurationForOneTime: DurationForOneTime
@@ -724,6 +728,7 @@ export type TypeAliasMap = {
724
728
  FixedRange: FixedRange
725
729
  FixedSustainedAnimistPowerCost: FixedSustainedAnimistPowerCost
726
730
  FixedVolume: FixedVolume
731
+ GemOrPreviousStoneProperty: GemOrPreviousStoneProperty
727
732
  GeneralAnimalCare: GeneralAnimalCare
728
733
  GeneralPrerequisites: GeneralPrerequisites
729
734
  GenericSkillsSelectOptionCategoryCategory: GenericSkillsSelectOptionCategoryCategory<unknown>
@@ -5477,6 +5482,11 @@ export interface Property {
5477
5482
  */
5478
5483
  check?: SkillCheck
5479
5484
 
5485
+ /**
5486
+ * The property’s derived specializations.
5487
+ */
5488
+ derivedSpecializations?: DerivedPropertySpecializations
5489
+
5480
5490
  /**
5481
5491
  * All translations for the entry, identified by IETF language tag (BCP47).
5482
5492
  */
@@ -5497,6 +5507,37 @@ export interface PropertyTranslation {
5497
5507
  name: string
5498
5508
  }
5499
5509
 
5510
+ export interface PropertySpecialization {
5511
+ /**
5512
+ * The associated property.
5513
+ */
5514
+ parent: Property_ID
5515
+
5516
+ /**
5517
+ * All translations for the entry, identified by IETF language tag (BCP47).
5518
+ */
5519
+ translations: {
5520
+ [localeId: string]: PropertySpecializationTranslation
5521
+ }
5522
+ }
5523
+
5524
+ /**
5525
+ * The entity’s identifier. A UUID or a locale code if it is registered as the locale entity.
5526
+ */
5527
+ export type PropertySpecialization_ID = string
5528
+
5529
+ export interface PropertySpecializationTranslation {
5530
+ /**
5531
+ * The property’s name.
5532
+ */
5533
+ name: string
5534
+ }
5535
+
5536
+ export type DerivedPropertySpecializations =
5537
+ | {
5538
+ kind: "Elements"
5539
+ }
5540
+
5500
5541
  export interface Aspect {
5501
5542
  /**
5502
5543
  * All translations for the entry, identified by IETF language tag (BCP47).
@@ -8683,6 +8724,11 @@ export interface Spell {
8683
8724
  */
8684
8725
  property: Property_ID
8685
8726
 
8727
+ /**
8728
+ * The associated property specialization.
8729
+ */
8730
+ propertySpecialization?: AnyPropertySpecializationIdentifier
8731
+
8686
8732
  /**
8687
8733
  * The tradition(s) the spell is available for. It may be *generally* available to all traditions or it may be only familiar in specific traditions.
8688
8734
  */
@@ -8745,6 +8791,16 @@ export interface SpellTranslation {
8745
8791
  errata?: Errata
8746
8792
  }
8747
8793
 
8794
+ export type AnyPropertySpecializationIdentifier =
8795
+ | {
8796
+ kind: "General"
8797
+ General: PropertySpecialization_ID
8798
+ }
8799
+ | {
8800
+ kind: "Element"
8801
+ Element: Element_ID
8802
+ }
8803
+
8748
8804
  /**
8749
8805
  * The tradition(s) the spell or ritual is available for. It may be *generally* available to all traditions or it may be only familiar in specific traditions.
8750
8806
  */
@@ -9190,6 +9246,11 @@ export interface Ritual {
9190
9246
  */
9191
9247
  property: Property_ID
9192
9248
 
9249
+ /**
9250
+ * The associated property specialization.
9251
+ */
9252
+ propertySpecialization?: AnyPropertySpecializationIdentifier
9253
+
9193
9254
  /**
9194
9255
  * The tradition(s) the ritual is available for. It may be *generally* available to all traditions or it may be only familiar in specific traditions.
9195
9256
  */
@@ -26130,6 +26191,11 @@ export interface GemOrPreciousStone {
26130
26191
  */
26131
26192
  weight?: Weight
26132
26193
 
26194
+ /**
26195
+ * The associated property.
26196
+ */
26197
+ property?: GemOrPreviousStoneProperty
26198
+
26133
26199
  /**
26134
26200
  * The prerequisites of the item, if any. Note that this is fully separate from the prerequisites of the item’s trade secret, which are defined independently from this.
26135
26201
  */
@@ -26167,7 +26233,7 @@ export interface GemOrPreciousStoneTranslation {
26167
26233
  /**
26168
26234
  * The color of the gem or stone.
26169
26235
  */
26170
- color: string
26236
+ color?: string
26171
26237
 
26172
26238
  /**
26173
26239
  * Note text.
@@ -26182,6 +26248,18 @@ export interface GemOrPreciousStoneTranslation {
26182
26248
  errata?: Errata
26183
26249
  }
26184
26250
 
26251
+ export interface GemOrPreviousStoneProperty {
26252
+ /**
26253
+ * The associated property.
26254
+ */
26255
+ base: Property_ID
26256
+
26257
+ /**
26258
+ * The associated property specialization.
26259
+ */
26260
+ specialization?: AnyPropertySpecializationIdentifier
26261
+ }
26262
+
26185
26263
  export interface IlluminationLightSource {
26186
26264
  /**
26187
26265
  * The cost in silverthalers.
@@ -1,3 +1,5 @@
1
+ import { isNotEmpty } from "@elyukai/utils/array/nonEmpty";
2
+ import { nullableToArray } from "@elyukai/utils/nullable";
1
3
  import { assertExhaustive } from "@elyukai/utils/typeSafety";
2
4
  import { Case } from "tsondb/schema/gen";
3
5
  const emptyDerivedEquipmentTradeSecretsCache = {
@@ -146,6 +148,19 @@ export const buildDerivedTradeSecretsCache = (database, settings) => {
146
148
  id: Case("FocusRule", settings.derivedTradeSecrets.requiredFocusRuleForTalismans),
147
149
  active: true,
148
150
  })),
151
+ ...nullableToArray(container.content.tradition === undefined || !isNotEmpty(container.content.tradition)
152
+ ? undefined
153
+ : container.content.tradition.length === 1
154
+ ? Case("Single", Case("Activatable", {
155
+ id: Case("BlessedTradition", container.content.tradition[0]),
156
+ active: true,
157
+ }))
158
+ : Case("Disjunction", {
159
+ list: container.content.tradition.map(tradition => Case("Activatable", {
160
+ id: Case("BlessedTradition", tradition),
161
+ active: true,
162
+ })),
163
+ })),
149
164
  ],
150
165
  src: container.content.src,
151
166
  translations: Object.fromEntries(Object.entries(container.content.translations).map(([lang, translation]) => [
@@ -1,7 +1,22 @@
1
1
  import * as DB from "tsondb/schema/dsl";
2
2
  export declare const Property: DB.Entity<"Property", {
3
3
  check: DB.MemberDecl<DB.IncludeIdentifier<[], DB.TypeAlias<"SkillCheck", DB.Array<DB.ReferenceIdentifier>, []>>, false>;
4
+ specializations: DB.MemberDecl<DB.ChildEntities<DB.Entity<"PropertySpecialization", {
5
+ parent: DB.MemberDecl<DB.ReferenceIdentifier, true>;
6
+ translations: DB.MemberDecl<DB.NestedEntityMap<"PropertySpecializationTranslation", {
7
+ name: DB.MemberDecl<DB.String, true>;
8
+ }>, true>;
9
+ }, "parent">>, true>;
10
+ derivedSpecializations: DB.MemberDecl<DB.IncludeIdentifier<[], DB.Enum<"DerivedPropertySpecializations", {
11
+ Elements: DB.EnumCase<null>;
12
+ }, []>>, false>;
4
13
  translations: DB.MemberDecl<DB.NestedEntityMap<"PropertyTranslation", {
5
14
  name: DB.MemberDecl<DB.String, true>;
6
15
  }>, true>;
7
16
  }, undefined>;
17
+ export declare const PropertySpecialization: DB.Entity<"PropertySpecialization", {
18
+ parent: DB.MemberDecl<DB.ReferenceIdentifier, true>;
19
+ translations: DB.MemberDecl<DB.NestedEntityMap<"PropertySpecializationTranslation", {
20
+ name: DB.MemberDecl<DB.String, true>;
21
+ }>, true>;
22
+ }, "parent">;
@@ -1,4 +1,5 @@
1
1
  import * as DB from "tsondb/schema/dsl";
2
+ import { PropertyIdentifier } from "./_Identifier.js";
2
3
  import { SkillCheck } from "./_SkillCheck.js";
3
4
  import { NestedTranslationMap } from "./Locale.js";
4
5
  export const Property = DB.Entity(import.meta.url, {
@@ -9,6 +10,14 @@ export const Property = DB.Entity(import.meta.url, {
9
10
  comment: "The property check’s attributes. Only the properties from the Core Rules have defined property checks.",
10
11
  type: DB.IncludeIdentifier(SkillCheck),
11
12
  }),
13
+ specializations: DB.Required({
14
+ comment: "The property’s specializations.",
15
+ type: DB.ChildEntities(PropertySpecialization),
16
+ }),
17
+ derivedSpecializations: DB.Optional({
18
+ comment: "The property’s derived specializations.",
19
+ type: DB.IncludeIdentifier(DerivedPropertySpecializations),
20
+ }),
12
21
  translations: NestedTranslationMap(DB.Required, "Property", DB.Object({
13
22
  name: DB.Required({
14
23
  comment: "The property’s name.",
@@ -24,3 +33,33 @@ export const Property = DB.Entity(import.meta.url, {
24
33
  },
25
34
  ],
26
35
  });
36
+ const DerivedPropertySpecializations = DB.Enum(import.meta.url, {
37
+ name: "DerivedPropertySpecializations",
38
+ values: () => ({
39
+ Elements: DB.EnumCase({ type: null }),
40
+ }),
41
+ });
42
+ export const PropertySpecialization = DB.Entity(import.meta.url, {
43
+ name: "PropertySpecialization",
44
+ namePlural: "PropertySpecializations",
45
+ type: () => DB.Object({
46
+ parent: DB.Required({
47
+ comment: "The associated property.",
48
+ type: PropertyIdentifier(),
49
+ }),
50
+ translations: NestedTranslationMap(DB.Required, "PropertySpecialization", DB.Object({
51
+ name: DB.Required({
52
+ comment: "The property’s name.",
53
+ type: DB.String({ minLength: 1 }),
54
+ }),
55
+ })),
56
+ }),
57
+ parentReferenceKey: "parent",
58
+ instanceDisplayName: {},
59
+ uniqueConstraints: [
60
+ {
61
+ entityMapKeyPath: "translations",
62
+ keyPathInEntityMap: "name",
63
+ },
64
+ ],
65
+ });
@@ -560,6 +560,10 @@ export declare const Ritual: DB.Entity<"Ritual", {
560
560
  }>, false>;
561
561
  }>, []>>>, []>>, true>;
562
562
  property: DB.MemberDecl<DB.ReferenceIdentifier, true>;
563
+ propertySpecialization: DB.MemberDecl<DB.IncludeIdentifier<[], DB.Enum<"AnyPropertySpecializationIdentifier", {
564
+ General: DB.EnumCase<DB.ReferenceIdentifier>;
565
+ Element: DB.EnumCase<DB.ReferenceIdentifier>;
566
+ }, []>>, false>;
563
567
  traditions: DB.MemberDecl<DB.IncludeIdentifier<[], DB.Enum<"SpellworkTraditions", {
564
568
  General: DB.EnumCase<null>;
565
569
  Specific: DB.EnumCase<DB.Array<DB.ReferenceIdentifier>>;
@@ -4,6 +4,7 @@ import { ActivatableSkillEffect } from "./_ActivatableSkillEffect.js";
4
4
  import { AffectedTargetCategories } from "./_ActivatableSkillTargetCategory.js";
5
5
  import { Enhancement } from "./_Enhancements.js";
6
6
  import { PropertyIdentifier } from "./_Identifier.js";
7
+ import { AnyPropertySpecializationIdentifier } from "./_IdentifierGroup.js";
7
8
  import { ImprovementCost } from "./_ImprovementCost.js";
8
9
  import { SpellworkPrerequisites } from "./_Prerequisite.js";
9
10
  import { SkillCheck, SkillCheckPenalty } from "./_SkillCheck.js";
@@ -35,6 +36,10 @@ export const Ritual = DB.Entity(import.meta.url, {
35
36
  comment: "The associated property.",
36
37
  type: PropertyIdentifier(),
37
38
  }),
39
+ propertySpecialization: DB.Optional({
40
+ comment: "The associated property specialization.",
41
+ type: DB.IncludeIdentifier(AnyPropertySpecializationIdentifier),
42
+ }),
38
43
  traditions: DB.Required({
39
44
  comment: "The tradition(s) the ritual is available for. It may be *generally* available to all traditions or it may be only familiar in specific traditions.",
40
45
  type: DB.IncludeIdentifier(SpellworkTraditions),
@@ -560,6 +560,10 @@ export declare const Spell: DB.Entity<"Spell", {
560
560
  }>, false>;
561
561
  }>, []>>>, []>>, true>;
562
562
  property: DB.MemberDecl<DB.ReferenceIdentifier, true>;
563
+ propertySpecialization: DB.MemberDecl<DB.IncludeIdentifier<[], DB.Enum<"AnyPropertySpecializationIdentifier", {
564
+ General: DB.EnumCase<DB.ReferenceIdentifier>;
565
+ Element: DB.EnumCase<DB.ReferenceIdentifier>;
566
+ }, []>>, false>;
563
567
  traditions: DB.MemberDecl<DB.IncludeIdentifier<[], DB.Enum<"SpellworkTraditions", {
564
568
  General: DB.EnumCase<null>;
565
569
  Specific: DB.EnumCase<DB.Array<DB.ReferenceIdentifier>>;
@@ -4,6 +4,7 @@ import { ActivatableSkillEffect } from "./_ActivatableSkillEffect.js";
4
4
  import { AffectedTargetCategories } from "./_ActivatableSkillTargetCategory.js";
5
5
  import { Enhancement } from "./_Enhancements.js";
6
6
  import { PropertyIdentifier } from "./_Identifier.js";
7
+ import { AnyPropertySpecializationIdentifier } from "./_IdentifierGroup.js";
7
8
  import { ImprovementCost } from "./_ImprovementCost.js";
8
9
  import { SpellworkPrerequisites } from "./_Prerequisite.js";
9
10
  import { SkillCheck, SkillCheckPenalty } from "./_SkillCheck.js";
@@ -35,6 +36,10 @@ export const Spell = DB.Entity(import.meta.url, {
35
36
  comment: "The associated property.",
36
37
  type: PropertyIdentifier(),
37
38
  }),
39
+ propertySpecialization: DB.Optional({
40
+ comment: "The associated property specialization.",
41
+ type: DB.IncludeIdentifier(AnyPropertySpecializationIdentifier),
42
+ }),
38
43
  traditions: DB.Required({
39
44
  comment: "The tradition(s) the spell is available for. It may be *generally* available to all traditions or it may be only familiar in specific traditions.",
40
45
  type: DB.IncludeIdentifier(SpellworkTraditions),
@@ -135,6 +135,7 @@ export declare const ProfessionPackageIdentifier: () => R;
135
135
  export declare const ProfessionVersionIdentifier: () => R;
136
136
  export declare const ProfessionVariantIdentifier: () => R;
137
137
  export declare const PropertyIdentifier: () => R;
138
+ export declare const PropertySpecializationIdentifier: () => R;
138
139
  export declare const ProtectiveWardingCircleSpecialAbilityIdentifier: () => R;
139
140
  export declare const PublicationIdentifier: () => R;
140
141
  export declare const RaceIdentifier: () => R;
@@ -87,7 +87,7 @@ import { Patron } from "./Patron.js";
87
87
  import { PatronCategory } from "./PatronCategory.js";
88
88
  import { PersonalityTrait } from "./PersonalityTrait.js";
89
89
  import { Profession, ProfessionPackage, ProfessionVariant, ProfessionVersion, } from "./Profession.js";
90
- import { Property } from "./Property.js";
90
+ import { Property, PropertySpecialization } from "./Property.js";
91
91
  import { Race, RaceVariant } from "./Race.js";
92
92
  import { Ritual } from "./Ritual.js";
93
93
  import { AlternativeRule } from "./rule/AlternativeRule.js";
@@ -305,6 +305,7 @@ export const ProfessionPackageIdentifier = () => R(ProfessionPackage);
305
305
  export const ProfessionVersionIdentifier = () => R(ProfessionVersion);
306
306
  export const ProfessionVariantIdentifier = () => R(ProfessionVariant);
307
307
  export const PropertyIdentifier = () => R(Property);
308
+ export const PropertySpecializationIdentifier = () => R(PropertySpecialization);
308
309
  export const ProtectiveWardingCircleSpecialAbilityIdentifier = () => R(PWCSpecialAbility);
309
310
  export const PublicationIdentifier = () => R(Publication);
310
311
  export const RaceIdentifier = () => R(Race);
@@ -480,3 +480,7 @@ export declare const TinyActivatableIdentifier: DB.Enum<"TinyActivatableIdentifi
480
480
  Blessing: DB.EnumCase<DB.ReferenceIdentifier>;
481
481
  Cantrip: DB.EnumCase<DB.ReferenceIdentifier>;
482
482
  }, []>;
483
+ export declare const AnyPropertySpecializationIdentifier: DB.Enum<"AnyPropertySpecializationIdentifier", {
484
+ General: DB.EnumCase<DB.ReferenceIdentifier>;
485
+ Element: DB.EnumCase<DB.ReferenceIdentifier>;
486
+ }, []>;
@@ -1,6 +1,6 @@
1
1
  import { sortObjectKeys } from "@elyukai/utils/object";
2
2
  import * as DB from "tsondb/schema/dsl";
3
- import { AdvancedCombatSpecialAbilityIdentifier, AdvancedKarmaSpecialAbilityIdentifier, AdvancedMagicalSpecialAbilityIdentifier, AdvancedSkillSpecialAbilityIdentifier, AdvantageIdentifier, AmmunitionIdentifier, AncestorGlyphIdentifier, AnimalCareIdentifier, AnimalIdentifier, AnimalShapeIdentifier, AnimalShapeSizeIdentifier, AnimistPowerIdentifier, ArcaneBardTraditionIdentifier, ArcaneDancerTraditionIdentifier, ArcaneOrbEnchantmentIdentifier, ArmorAccessoryIdentifier, ArmorIdentifier, AspectIdentifier, AttireEnchantmentIdentifier, AttributeIdentifier, BandageOrRemedyIdentifier, BannzeichenIdentifier, BeutelzauberIdentifier, BlessedTraditionIdentifier, BlessingIdentifier, BookIdentifier, BowlEnchantmentIdentifier, BrawlingSpecialAbilityIdentifier, CantripIdentifier, CauldronEnchantmentIdentifier, CeremonialItemIdentifier, CeremonialItemSpecialAbilityIdentifier, CeremonyIdentifier, ChronicleEnchantmentIdentifier, CloseCombatTechniqueIdentifier, ClothesIdentifier, ClothingPackageIdentifier, CombatSpecialAbilityIdentifier, CombatStyleSpecialAbilityIdentifier, CommandSpecialAbilityIdentifier, ContainerIdentifier, CultureIdentifier, CurseIdentifier, DaggerRitualIdentifier, DisadvantageIdentifier, DiseaseIdentifier, DominationRitualIdentifier, ElementIdentifier, ElixirIdentifier, ElvenMagicalSongIdentifier, EnhancementIdentifier, EquipmentOfBlessedOnesIdentifier, FamiliarSpecialAbilityIdentifier, FatePointSexSpecialAbilityIdentifier, FatePointSpecialAbilityIdentifier, FocusRuleIdentifier, FoolsHatEnchantmentIdentifier, GemOrPreciousStoneIdentifier, GeneralIdentifier, GeneralSpecialAbilityIdentifier, GeodeRitualIdentifier, GoblinRitualIdentifier, HaubenzauberIdentifier, HauerkettenzauberIdentifier, IlluminationLightSourceIdentifier, IlluminationRefillOrSupplyIdentifier, InstrumentEnchantmentIdentifier, ItemComponentIdentifier, JesterTrickIdentifier, JewelryIdentifier, KarmaSpecialAbilityIdentifier, KeulenzauberIdentifier, KrallenkettenzauberIdentifier, KristallkugelzauberIdentifier, LaboratoryIdentifier, LanguageIdentifier, LiebesspielzeugIdentifier, LiturgicalChantIdentifier, LiturgicalStyleSpecialAbilityIdentifier, LuxuryGoodIdentifier, LycantropicGiftIdentifier, MagicalArtifactIdentifier, MagicalDanceIdentifier, MagicalMelodyIdentifier, MagicalRuneIdentifier, MagicalSignIdentifier, MagicalSpecialAbilityIdentifier, MagicalTraditionIdentifier, MagicStyleSpecialAbilityIdentifier, MusicalInstrumentIdentifier, NewspaperIdentifier, OptionalRuleIdentifier, OrbEnchantmentIdentifier, OrienteeringAidIdentifier, PactGiftIdentifier, PatronIdentifier, PoisonIdentifier, PropertyIdentifier, ProtectiveWardingCircleSpecialAbilityIdentifier, RaceIdentifier, RangedCombatTechniqueIdentifier, RingEnchantmentIdentifier, RitualIdentifier, RopeOrChainIdentifier, SchweinetrommelzauberIdentifier, ScriptIdentifier, SermonIdentifier, SexPracticeIdentifier, SexSpecialAbilityIdentifier, SickleRitualIdentifier, SikaryanDrainSpecialAbilityIdentifier, SkillApplicationIdentifier, SkillGroupIdentifier, SkillIdentifier, SkillStyleSpecialAbilityIdentifier, SpellIdentifier, SpellSwordEnchantmentIdentifier, StaffEnchantmentIdentifier, StationeryIdentifier, TargetCategoryIdentifier, ThievesToolIdentifier, ToolOfTheTradeIdentifier, ToyEnchantmentIdentifier, TradeSecretIdentifier, TravelGearOrToolIdentifier, TrinkhornzauberIdentifier, VampiricGiftIdentifier, VehicleIdentifier, VisionIdentifier, WandEnchantmentIdentifier, WeaponAccessoryIdentifier, WeaponEnchantmentIdentifier, WeaponIdentifier, WorkingSupernaturalCreatureIdentifier, ZibiljaRitualIdentifier, } from "./_Identifier.js";
3
+ import { AdvancedCombatSpecialAbilityIdentifier, AdvancedKarmaSpecialAbilityIdentifier, AdvancedMagicalSpecialAbilityIdentifier, AdvancedSkillSpecialAbilityIdentifier, AdvantageIdentifier, AmmunitionIdentifier, AncestorGlyphIdentifier, AnimalCareIdentifier, AnimalIdentifier, AnimalShapeIdentifier, AnimalShapeSizeIdentifier, AnimistPowerIdentifier, ArcaneBardTraditionIdentifier, ArcaneDancerTraditionIdentifier, ArcaneOrbEnchantmentIdentifier, ArmorAccessoryIdentifier, ArmorIdentifier, AspectIdentifier, AttireEnchantmentIdentifier, AttributeIdentifier, BandageOrRemedyIdentifier, BannzeichenIdentifier, BeutelzauberIdentifier, BlessedTraditionIdentifier, BlessingIdentifier, BookIdentifier, BowlEnchantmentIdentifier, BrawlingSpecialAbilityIdentifier, CantripIdentifier, CauldronEnchantmentIdentifier, CeremonialItemIdentifier, CeremonialItemSpecialAbilityIdentifier, CeremonyIdentifier, ChronicleEnchantmentIdentifier, CloseCombatTechniqueIdentifier, ClothesIdentifier, ClothingPackageIdentifier, CombatSpecialAbilityIdentifier, CombatStyleSpecialAbilityIdentifier, CommandSpecialAbilityIdentifier, ContainerIdentifier, CultureIdentifier, CurseIdentifier, DaggerRitualIdentifier, DisadvantageIdentifier, DiseaseIdentifier, DominationRitualIdentifier, ElementIdentifier, ElixirIdentifier, ElvenMagicalSongIdentifier, EnhancementIdentifier, EquipmentOfBlessedOnesIdentifier, FamiliarSpecialAbilityIdentifier, FatePointSexSpecialAbilityIdentifier, FatePointSpecialAbilityIdentifier, FocusRuleIdentifier, FoolsHatEnchantmentIdentifier, GemOrPreciousStoneIdentifier, GeneralIdentifier, GeneralSpecialAbilityIdentifier, GeodeRitualIdentifier, GoblinRitualIdentifier, HaubenzauberIdentifier, HauerkettenzauberIdentifier, IlluminationLightSourceIdentifier, IlluminationRefillOrSupplyIdentifier, InstrumentEnchantmentIdentifier, ItemComponentIdentifier, JesterTrickIdentifier, JewelryIdentifier, KarmaSpecialAbilityIdentifier, KeulenzauberIdentifier, KrallenkettenzauberIdentifier, KristallkugelzauberIdentifier, LaboratoryIdentifier, LanguageIdentifier, LiebesspielzeugIdentifier, LiturgicalChantIdentifier, LiturgicalStyleSpecialAbilityIdentifier, LuxuryGoodIdentifier, LycantropicGiftIdentifier, MagicalArtifactIdentifier, MagicalDanceIdentifier, MagicalMelodyIdentifier, MagicalRuneIdentifier, MagicalSignIdentifier, MagicalSpecialAbilityIdentifier, MagicalTraditionIdentifier, MagicStyleSpecialAbilityIdentifier, MusicalInstrumentIdentifier, NewspaperIdentifier, OptionalRuleIdentifier, OrbEnchantmentIdentifier, OrienteeringAidIdentifier, PactGiftIdentifier, PatronIdentifier, PoisonIdentifier, PropertyIdentifier, PropertySpecializationIdentifier, ProtectiveWardingCircleSpecialAbilityIdentifier, RaceIdentifier, RangedCombatTechniqueIdentifier, RingEnchantmentIdentifier, RitualIdentifier, RopeOrChainIdentifier, SchweinetrommelzauberIdentifier, ScriptIdentifier, SermonIdentifier, SexPracticeIdentifier, SexSpecialAbilityIdentifier, SickleRitualIdentifier, SikaryanDrainSpecialAbilityIdentifier, SkillApplicationIdentifier, SkillGroupIdentifier, SkillIdentifier, SkillStyleSpecialAbilityIdentifier, SpellIdentifier, SpellSwordEnchantmentIdentifier, StaffEnchantmentIdentifier, StationeryIdentifier, TargetCategoryIdentifier, ThievesToolIdentifier, ToolOfTheTradeIdentifier, ToyEnchantmentIdentifier, TradeSecretIdentifier, TravelGearOrToolIdentifier, TrinkhornzauberIdentifier, VampiricGiftIdentifier, VehicleIdentifier, VisionIdentifier, WandEnchantmentIdentifier, WeaponAccessoryIdentifier, WeaponEnchantmentIdentifier, WeaponIdentifier, WorkingSupernaturalCreatureIdentifier, ZibiljaRitualIdentifier, } from "./_Identifier.js";
4
4
  export const ActivatableIdentifier = DB.Enum(import.meta.url, {
5
5
  name: "ActivatableIdentifier",
6
6
  values: () => ({
@@ -364,3 +364,10 @@ export const TinyActivatableIdentifier = DB.Enum(import.meta.url, {
364
364
  Cantrip: DB.EnumCase({ type: CantripIdentifier() }),
365
365
  }),
366
366
  });
367
+ export const AnyPropertySpecializationIdentifier = DB.Enum(import.meta.url, {
368
+ name: "AnyPropertySpecializationIdentifier",
369
+ values: () => ({
370
+ General: DB.EnumCase({ type: PropertySpecializationIdentifier() }),
371
+ Element: DB.EnumCase({ type: ElementIdentifier() }),
372
+ }),
373
+ });
@@ -23,6 +23,13 @@ export declare const GemOrPreciousStone: DB.Entity<"GemOrPreciousStone", {
23
23
  }>, []>>>;
24
24
  }, []>>, true>;
25
25
  weight: DB.MemberDecl<DB.IncludeIdentifier<[], DB.TypeAlias<"Weight", DB.Float, []>>, false>;
26
+ property: DB.MemberDecl<DB.IncludeIdentifier<[], DB.TypeAlias<"GemOrPreviousStoneProperty", DB.Object<{
27
+ base: DB.MemberDecl<DB.ReferenceIdentifier, true>;
28
+ specialization: DB.MemberDecl<DB.IncludeIdentifier<[], DB.Enum<"AnyPropertySpecializationIdentifier", {
29
+ General: DB.EnumCase<DB.ReferenceIdentifier>;
30
+ Element: DB.EnumCase<DB.ReferenceIdentifier>;
31
+ }, []>>, false>;
32
+ }>, []>>, false>;
26
33
  prerequisites: DB.MemberDecl<DB.IncludeIdentifier<[], DB.TypeAlias<"EquipmentPrerequisites", DB.IncludeIdentifier<DB.Param<string, DB.Type>[], DB.TypeAlias<"PlainPrerequisites", DB.Array<DB.IncludeIdentifier<DB.Param<string, DB.Type>[], DB.Enum<"PrerequisitesElement", {
27
34
  Single: DB.EnumCase<DB.TypeArgument<DB.Param<"T", DB.Type>>>;
28
35
  Disjunction: DB.EnumCase<DB.IncludeIdentifier<DB.Param<string, DB.Type>[], DB.TypeAlias<"PrerequisitesDisjunction", DB.Object<{
@@ -91,7 +98,7 @@ export declare const GemOrPreciousStone: DB.Entity<"GemOrPreciousStone", {
91
98
  translations: DB.MemberDecl<DB.NestedEntityMap<"GemOrPreciousStoneTranslation", {
92
99
  name: DB.MemberDecl<DB.String, true>;
93
100
  secondary_name: DB.MemberDecl<DB.String, false>;
94
- color: DB.MemberDecl<DB.String, true>;
101
+ color: DB.MemberDecl<DB.String, false>;
95
102
  note: DB.MemberDecl<DB.String, false>;
96
103
  rules: DB.MemberDecl<DB.String, false>;
97
104
  errata: DB.MemberDecl<DB.IncludeIdentifier<[], DB.TypeAlias<"Errata", DB.Array<DB.IncludeIdentifier<[], DB.TypeAlias<"Erratum", DB.Object<{
@@ -1,4 +1,6 @@
1
1
  import * as DB from "tsondb/schema/dsl";
2
+ import { PropertyIdentifier } from "../../_Identifier.js";
3
+ import { AnyPropertySpecializationIdentifier } from "../../_IdentifierGroup.js";
2
4
  import { EquipmentPrerequisites } from "../../_Prerequisite.js";
3
5
  import { NestedTranslationMap } from "../../Locale.js";
4
6
  import { Errata } from "../../source/_Erratum.js";
@@ -16,6 +18,10 @@ export const GemOrPreciousStone = DB.Entity(import.meta.url, {
16
18
  comment: "The weight in kg.",
17
19
  type: DB.IncludeIdentifier(Weight),
18
20
  }),
21
+ property: DB.Optional({
22
+ comment: "The associated property.",
23
+ type: DB.IncludeIdentifier(GemOrPreviousStoneProperty),
24
+ }),
19
25
  prerequisites: DB.Optional({
20
26
  comment: "The prerequisites of the item, if any. Note that this is fully separate from the prerequisites of the item’s trade secret, which are defined independently from this.",
21
27
  type: DB.IncludeIdentifier(EquipmentPrerequisites),
@@ -30,7 +36,7 @@ export const GemOrPreciousStone = DB.Entity(import.meta.url, {
30
36
  comment: "An auxiliary name or label of the item, if available.",
31
37
  type: DB.String({ minLength: 1 }),
32
38
  }),
33
- color: DB.Required({
39
+ color: DB.Optional({
34
40
  comment: "The color of the gem or stone.",
35
41
  type: DB.String({ minLength: 1 }),
36
42
  }),
@@ -55,3 +61,16 @@ export const GemOrPreciousStone = DB.Entity(import.meta.url, {
55
61
  },
56
62
  ],
57
63
  });
64
+ const GemOrPreviousStoneProperty = DB.TypeAlias(import.meta.url, {
65
+ name: "GemOrPreviousStoneProperty",
66
+ type: () => DB.Object({
67
+ base: DB.Required({
68
+ comment: "The associated property.",
69
+ type: PropertyIdentifier(),
70
+ }),
71
+ specialization: DB.Optional({
72
+ comment: "The associated property specialization.",
73
+ type: DB.IncludeIdentifier(AnyPropertySpecializationIdentifier),
74
+ }),
75
+ }),
76
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@optolith/database-schema",
3
- "version": "0.107.1",
3
+ "version": "0.108.1",
4
4
  "description": "Definitions and utilities for the flat-file database of Optolith, a character creation tool for the Pen and Paper RPG “The Dark Eye 5”, and its external integrations into other software.",
5
5
  "keywords": [
6
6
  "tde",