@optolith/database-schema 0.82.0 → 0.84.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,34 @@
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.84.0](https://github.com/Optolith/database-schema/compare/v0.83.0...v0.84.0) (2026-10-07)
6
+
7
+ ### ⚠ BREAKING CHANGES
8
+
9
+ * include professions by mundane profession group
10
+
11
+ ### Features
12
+
13
+ * associate profession with magical tradition subgroup ([f0a2838](https://github.com/Optolith/database-schema/commit/f0a28389c00c5b522c43197f6d278e121e391692))
14
+ * include professions by mundane profession group ([a147553](https://github.com/Optolith/database-schema/commit/a147553a72f050b4905b7b640fb781161f7888bc))
15
+ * magical tradition subgroup child entity ([577fdb6](https://github.com/Optolith/database-schema/commit/577fdb6455e69cec086349209dc3e610a2d8d865))
16
+
17
+ ## [0.83.0](https://github.com/Optolith/database-schema/compare/v0.82.0...v0.83.0) (2026-10-06)
18
+
19
+ ### ⚠ BREAKING CHANGES
20
+
21
+ * different duration translation for diseases
22
+ * various plant schema improvements
23
+
24
+ ### Features
25
+
26
+ * additional text for reduceable effects ([71743e8](https://github.com/Optolith/database-schema/commit/71743e82039d7aa0523c7ded646ad8d3f145ceed))
27
+ * various plant schema improvements ([c4cb673](https://github.com/Optolith/database-schema/commit/c4cb673685d2ae817ae5705d6b8625d7e80cc60f))
28
+
29
+ ### Bug Fixes
30
+
31
+ * different duration translation for diseases ([ef682b2](https://github.com/Optolith/database-schema/commit/ef682b28fe358b13f69250ec09c5607154754b3b))
32
+
5
33
  ## [0.82.0](https://github.com/Optolith/database-schema/compare/v0.81.0...v0.82.0) (2026-10-06)
6
34
 
7
35
  ### ⚠ BREAKING CHANGES
package/gen/types.d.ts CHANGED
@@ -117,6 +117,7 @@ export type EntityMap = {
117
117
  MagicalSign: MagicalSign
118
118
  MagicalSpecialAbility: MagicalSpecialAbility
119
119
  MagicalTradition: MagicalTradition
120
+ MagicalTraditionSubgroup: MagicalTraditionSubgroup
120
121
  MagicStyleSpecialAbility: MagicStyleSpecialAbility
121
122
  MetaCondition: MetaCondition
122
123
  MusicalInstrument: MusicalInstrument
@@ -204,6 +205,7 @@ export type ChildEntityMap = {
204
205
  LanguageSpecialization: [LanguageSpecialization, "parent", LanguageSpecialization["parent"]]
205
206
  LessonPackage: [LessonPackage, "curriculum", LessonPackage["curriculum"]]
206
207
  MagicalRuneOption: [MagicalRuneOption, "parent", MagicalRuneOption["parent"]]
208
+ MagicalTraditionSubgroup: [MagicalTraditionSubgroup, "parent", MagicalTraditionSubgroup["parent"]]
207
209
  NewSkillApplication: [NewSkillApplication, "parent", NewSkillApplication["parent"]]
208
210
  PactDomain: [PactDomain, "parent", PactDomain["parent"]]
209
211
  PactType: [PactType, "parent", PactType["parent"]]
@@ -2746,6 +2748,7 @@ export interface Locale {
2746
2748
  "Progress": string
2747
2749
  "Incubation Time": string
2748
2750
  "Damage": string
2751
+ "Duration (Disease)": string
2749
2752
  "Causes": string
2750
2753
  "Treatment": string
2751
2754
  "Antidote": string
@@ -5847,6 +5850,11 @@ export interface Reduceable<Content> {
5847
5850
  * The reduced value. In the source, it's the text after the slash. Some entries may not have a reduced value, i.e. there is no slash with text after it. If the text after the slash is a dash, include it here as well.
5848
5851
  */
5849
5852
  reduced?: Content
5853
+
5854
+ /**
5855
+ * An additional text that applies regardless of the effect being reduced or not.
5856
+ */
5857
+ additonal?: string
5850
5858
  }
5851
5859
 
5852
5860
  export interface Poison {
@@ -6383,6 +6391,9 @@ export type ExpressionBasedPoisonTimeExpressionValue =
6383
6391
  | {
6384
6392
  kind: "CircleOfDamnation"
6385
6393
  }
6394
+ | {
6395
+ kind: "QualityLevels"
6396
+ }
6386
6397
 
6387
6398
  export type PoisonTimeUnit =
6388
6399
  | {
@@ -8676,7 +8687,7 @@ export interface MagicalTradition {
8676
8687
  use_arcane_spellworks_from_tradition?: MagicalTradition_ID
8677
8688
 
8678
8689
  /**
8679
- * The influences for the traditions. Influences are enabled by Focus Rules.
8690
+ * The influences for the tradition. Influences are enabled by Focus Rules.
8680
8691
  */
8681
8692
  influences?: Influence_ID[]
8682
8693
 
@@ -8894,6 +8905,11 @@ export interface MagicalProfessionGroup {
8894
8905
  * The curriculum/academy associated with this magical profession, if any.
8895
8906
  */
8896
8907
  curriculum?: Curriculum_ID
8908
+
8909
+ /**
8910
+ * The tradition’s subgroup associated with this magical profession, if any.
8911
+ */
8912
+ subgroup?: Curriculum_ID
8897
8913
  }
8898
8914
 
8899
8915
  /**
@@ -10019,6 +10035,10 @@ export type MundaneCommonProfessionConstraint =
10019
10035
  kind: "Profession"
10020
10036
  Profession: ProfessionConstraint
10021
10037
  }
10038
+ | {
10039
+ kind: "Group"
10040
+ Group: MundaneProfessionGroup
10041
+ }
10022
10042
 
10023
10043
  export interface ProfessionConstraint {
10024
10044
  /**
@@ -20955,6 +20975,32 @@ export interface InfluenceEffect {
20955
20975
  text: string
20956
20976
  }
20957
20977
 
20978
+ export interface MagicalTraditionSubgroup {
20979
+ /**
20980
+ * The magical tradition this subgroup belongs to.
20981
+ */
20982
+ parent: MagicalTradition_ID
20983
+
20984
+ /**
20985
+ * All translations for the entry, identified by IETF language tag (BCP47).
20986
+ */
20987
+ translations: {
20988
+ [localeId: string]: MagicalTraditionSubgroupTranslation
20989
+ }
20990
+ }
20991
+
20992
+ /**
20993
+ * The entity’s identifier. A UUID or a locale code if it is registered as the locale entity.
20994
+ */
20995
+ export type MagicalTraditionSubgroup_ID = string
20996
+
20997
+ export interface MagicalTraditionSubgroupTranslation {
20998
+ /**
20999
+ * The name of the ceremonial item. This should be the heading used in the respective publication.
21000
+ */
21001
+ name: string
21002
+ }
21003
+
20958
21004
  /**
20959
21005
  * Defines how to determine the AP cost of an enhancement.
20960
21006
  */
@@ -26799,6 +26845,9 @@ export interface PlantOccurrenceTranslation {
26799
26845
  }
26800
26846
 
26801
26847
  export type PlantOccurrenceTier =
26848
+ | {
26849
+ kind: "AllBiomes"
26850
+ }
26802
26851
  | {
26803
26852
  kind: "Biomes"
26804
26853
  Biomes: Biome_ID[]
package/lib/main.js CHANGED
@@ -109,6 +109,7 @@ export const schema = new Schema([
109
109
  Types.MagicalSign,
110
110
  Types.MagicalSpecialAbility,
111
111
  Types.MagicalTradition,
112
+ Types.MagicalTraditionSubgroup,
112
113
  Types.MagicStyleSpecialAbility,
113
114
  Types.MetaCondition,
114
115
  Types.MusicalInstrument,
@@ -79,10 +79,12 @@ export declare const AnimalDisease: DB.Entity<"AnimalDisease", {
79
79
  damage: DB.MemberDecl<DB.IncludeIdentifier<DB.Param<string, DB.Type>[], DB.TypeAlias<"Reduceable", DB.Object<{
80
80
  default: DB.MemberDecl<DB.TypeArgument<DB.Param<"Content", DB.Type>>, true>;
81
81
  reduced: DB.MemberDecl<DB.TypeArgument<DB.Param<"Content", DB.Type>>, false>;
82
+ additonal: DB.MemberDecl<DB.String, false>;
82
83
  }>, [Content: DB.Param<"Content", DB.Type>]>>, true>;
83
84
  duration: DB.MemberDecl<DB.IncludeIdentifier<DB.Param<string, DB.Type>[], DB.TypeAlias<"Reduceable", DB.Object<{
84
85
  default: DB.MemberDecl<DB.TypeArgument<DB.Param<"Content", DB.Type>>, true>;
85
86
  reduced: DB.MemberDecl<DB.TypeArgument<DB.Param<"Content", DB.Type>>, false>;
87
+ additonal: DB.MemberDecl<DB.String, false>;
86
88
  }>, [Content: DB.Param<"Content", DB.Type>]>>, true>;
87
89
  special: DB.MemberDecl<DB.String, false>;
88
90
  treatment: DB.MemberDecl<DB.String, true>;
@@ -3,6 +3,7 @@ import { CommonnessRatedAdvantageDisadvantage } from "./_CommonnessRatedAdvantag
3
3
  import { AdvantageIdentifier, BlessedTraditionIdentifier, DisadvantageIdentifier, LanguageIdentifier, LanguageSpecializationIdentifier, MagicalTraditionIdentifier, ProfessionIdentifier, ProfessionVariantIdentifier, ScriptIdentifier, SkillIdentifier, SocialStatusIdentifier, } from "./_Identifier.js";
4
4
  import { BinarySex } from "./_Sex.js";
5
5
  import { NestedTranslationMap } from "./Locale.js";
6
+ import { MundaneProfessionGroup } from "./Profession.js";
6
7
  import { Errata } from "./source/_Erratum.js";
7
8
  import { src } from "./source/_PublicationRef.js";
8
9
  export const Culture = DB.Entity(import.meta.url, {
@@ -247,6 +248,7 @@ const MundaneCommonProfessionConstraint = DB.Enum(import.meta.url, {
247
248
  name: "MundaneCommonProfessionConstraint",
248
249
  values: () => ({
249
250
  Profession: DB.EnumCase({ type: DB.IncludeIdentifier(ProfessionConstraint) }),
251
+ Group: DB.EnumCase({ type: DB.IncludeIdentifier(MundaneProfessionGroup) }),
250
252
  }),
251
253
  });
252
254
  const MagicCommonProfessionConstraint = DB.Enum(import.meta.url, {
@@ -141,10 +141,12 @@ export declare const Disease: DB.Entity<"Disease", {
141
141
  damage: DB.MemberDecl<DB.IncludeIdentifier<DB.Param<string, DB.Type>[], DB.TypeAlias<"Reduceable", DB.Object<{
142
142
  default: DB.MemberDecl<DB.TypeArgument<DB.Param<"Content", DB.Type>>, true>;
143
143
  reduced: DB.MemberDecl<DB.TypeArgument<DB.Param<"Content", DB.Type>>, false>;
144
+ additonal: DB.MemberDecl<DB.String, false>;
144
145
  }>, [Content: DB.Param<"Content", DB.Type>]>>, true>;
145
146
  duration: DB.MemberDecl<DB.IncludeIdentifier<DB.Param<string, DB.Type>[], DB.TypeAlias<"Reduceable", DB.Object<{
146
147
  default: DB.MemberDecl<DB.TypeArgument<DB.Param<"Content", DB.Type>>, true>;
147
148
  reduced: DB.MemberDecl<DB.TypeArgument<DB.Param<"Content", DB.Type>>, false>;
149
+ additonal: DB.MemberDecl<DB.String, false>;
148
150
  }>, [Content: DB.Param<"Content", DB.Type>]>>, true>;
149
151
  special: DB.MemberDecl<DB.String, false>;
150
152
  treatment: DB.MemberDecl<DB.String, true>;
@@ -1607,6 +1607,7 @@ export declare const Locale: DB.Entity<"Locale", {
1607
1607
  Progress: null;
1608
1608
  "Incubation Time": null;
1609
1609
  Damage: null;
1610
+ "Duration (Disease)": null;
1610
1611
  Causes: null;
1611
1612
  Treatment: null;
1612
1613
  Antidote: null;
@@ -1654,6 +1654,7 @@ export const Locale = DB.Entity(import.meta.url, {
1654
1654
  "Progress": null,
1655
1655
  "Incubation Time": null,
1656
1656
  "Damage": null,
1657
+ "Duration (Disease)": null,
1657
1658
  "Causes": null,
1658
1659
  "Treatment": null,
1659
1660
  "Antidote": null,
@@ -8,6 +8,7 @@ export declare const Profession: DB.Entity<"Profession", {
8
8
  }, []>>>;
9
9
  Magical: DB.EnumCase<DB.IncludeIdentifier<[], DB.TypeAlias<"MagicalProfessionGroup", DB.Object<{
10
10
  curriculum: DB.MemberDecl<DB.ReferenceIdentifier, false>;
11
+ subgroup: DB.MemberDecl<DB.ReferenceIdentifier, false>;
11
12
  }>, []>>>;
12
13
  Blessed: DB.EnumCase<null>;
13
14
  }, []>>, true>;
@@ -64,6 +64,10 @@ const MagicalProfessionGroup = DB.TypeAlias(import.meta.url, {
64
64
  comment: "The curriculum/academy associated with this magical profession, if any.",
65
65
  type: CurriculumIdentifier(),
66
66
  }),
67
+ subgroup: DB.Optional({
68
+ comment: "The tradition’s subgroup associated with this magical profession, if any.",
69
+ type: CurriculumIdentifier(),
70
+ }),
67
71
  }),
68
72
  });
69
73
  export const ProfessionVersion = DB.Entity(import.meta.url, {
@@ -38,6 +38,7 @@ export declare const cause: DB.MemberDecl<DB.Array<DB.IncludeIdentifier<[], DB.T
38
38
  export declare const Reduceable: DB.TypeAlias<"Reduceable", DB.Object<{
39
39
  default: DB.MemberDecl<DB.TypeArgument<DB.Param<"Content", DB.Type>>, true>;
40
40
  reduced: DB.MemberDecl<DB.TypeArgument<DB.Param<"Content", DB.Type>>, false>;
41
+ additonal: DB.MemberDecl<DB.String, false>;
41
42
  }>, [Content: DB.Param<"Content", DB.Type>]>;
42
43
  export declare const DiseaseTranslation: DB.Object<{
43
44
  name: DB.MemberDecl<DB.String, true>;
@@ -51,10 +52,12 @@ export declare const DiseaseTranslation: DB.Object<{
51
52
  damage: DB.MemberDecl<DB.IncludeIdentifier<DB.Param<string, DB.Type>[], DB.TypeAlias<"Reduceable", DB.Object<{
52
53
  default: DB.MemberDecl<DB.TypeArgument<DB.Param<"Content", DB.Type>>, true>;
53
54
  reduced: DB.MemberDecl<DB.TypeArgument<DB.Param<"Content", DB.Type>>, false>;
55
+ additonal: DB.MemberDecl<DB.String, false>;
54
56
  }>, [Content: DB.Param<"Content", DB.Type>]>>, true>;
55
57
  duration: DB.MemberDecl<DB.IncludeIdentifier<DB.Param<string, DB.Type>[], DB.TypeAlias<"Reduceable", DB.Object<{
56
58
  default: DB.MemberDecl<DB.TypeArgument<DB.Param<"Content", DB.Type>>, true>;
57
59
  reduced: DB.MemberDecl<DB.TypeArgument<DB.Param<"Content", DB.Type>>, false>;
60
+ additonal: DB.MemberDecl<DB.String, false>;
58
61
  }>, [Content: DB.Param<"Content", DB.Type>]>>, true>;
59
62
  special: DB.MemberDecl<DB.String, false>;
60
63
  treatment: DB.MemberDecl<DB.String, true>;
@@ -100,6 +100,10 @@ This streamlines the wording for diseases and poison by using a unified wording
100
100
  comment: "The reduced value. In the source, it's the text after the slash. Some entries may not have a reduced value, i.e. there is no slash with text after it. If the text after the slash is a dash, include it here as well.",
101
101
  type: DB.TypeArgument(Content),
102
102
  }),
103
+ additonal: DB.Optional({
104
+ comment: "An additional text that applies regardless of the effect being reduced or not.",
105
+ type: DB.String({ minLength: 1, markdown: "inline" }),
106
+ }),
103
107
  }),
104
108
  });
105
109
  export const DiseaseTranslation = DB.Object({
@@ -110,6 +110,7 @@ export declare const MagicalRuneOptionIdentifier: () => R;
110
110
  export declare const MagicalSignIdentifier: () => R;
111
111
  export declare const MagicalSpecialAbilityIdentifier: () => R;
112
112
  export declare const MagicalTraditionIdentifier: () => R;
113
+ export declare const MagicalTraditionSubgroupIdentifier: () => R;
113
114
  export declare const MagicStyleSpecialAbilityIdentifier: () => R;
114
115
  export declare const MusicalInstrumentIdentifier: () => R;
115
116
  export declare const NewspaperIdentifier: () => R;
@@ -130,6 +130,7 @@ import { SikaryanDrainSpecialAbility } from "./specialAbility/SikaryanDrainSpeci
130
130
  import { SkillStyleSpecialAbility } from "./specialAbility/SkillStyleSpecialAbility.js";
131
131
  import { CeremonialItemSpecialAbilityGroup } from "./specialAbility/sub/CeremonialItemSpecialAbilityGroup.js";
132
132
  import { Language, LanguageSpecialization } from "./specialAbility/sub/Language.js";
133
+ import { MagicalTraditionSubgroup } from "./specialAbility/sub/MagicalTraditionSubgroup.js";
133
134
  import { Script } from "./specialAbility/sub/Script.js";
134
135
  import { TradeSecret } from "./specialAbility/sub/TradeSecret.js";
135
136
  import { VampiricGift } from "./specialAbility/VampiricGift.js";
@@ -276,6 +277,7 @@ export const MagicalRuneOptionIdentifier = () => R(MagicalRuneOption);
276
277
  export const MagicalSignIdentifier = () => R(MagicalSign);
277
278
  export const MagicalSpecialAbilityIdentifier = () => R(MagicalSpecialAbility);
278
279
  export const MagicalTraditionIdentifier = () => R(MagicalTradition);
280
+ export const MagicalTraditionSubgroupIdentifier = () => R(MagicalTraditionSubgroup);
279
281
  export const MagicStyleSpecialAbilityIdentifier = () => R(MagicStyleSpecialAbility);
280
282
  export const MusicalInstrumentIdentifier = () => R(MusicalInstrument);
281
283
  export const NewspaperIdentifier = () => R(Newspaper);
@@ -12,6 +12,7 @@ export declare const Plant: DB.Entity<"Plant", {
12
12
  occurences: DB.MemberDecl<DB.IncludeIdentifier<[], DB.TypeAlias<"PlantOccurences", DB.Object<{
13
13
  items: DB.MemberDecl<DB.Array<DB.IncludeIdentifier<[], DB.TypeAlias<"PlantOccurrence", DB.Object<{
14
14
  regions: DB.MemberDecl<DB.IncludeIdentifier<[], DB.Enum<"PlantOccurrenceTier", {
15
+ AllBiomes: DB.EnumCase<null>;
15
16
  Biomes: DB.EnumCase<DB.Array<DB.ReferenceIdentifier>>;
16
17
  SubBiomes: DB.EnumCase<DB.Array<DB.ReferenceIdentifier>>;
17
18
  BotanicRegions: DB.EnumCase<DB.Array<DB.ReferenceIdentifier>>;
@@ -123,6 +123,7 @@ const PlantOccurrence = DB.TypeAlias(import.meta.url, {
123
123
  const PlantOccurrenceTier = DB.Enum(import.meta.url, {
124
124
  name: "PlantOccurrenceTier",
125
125
  values: () => ({
126
+ AllBiomes: DB.EnumCase({ type: null }),
126
127
  Biomes: DB.EnumCase({
127
128
  type: DB.Array(BiomeIdentifier(), { minItems: 1 }),
128
129
  }),
@@ -316,6 +316,7 @@ export declare const Poison: DB.Entity<"Poison", {
316
316
  duration: DB.MemberDecl<DB.IncludeIdentifier<DB.Param<string, DB.Type>[], DB.TypeAlias<"Reduceable", DB.Object<{
317
317
  default: DB.MemberDecl<DB.TypeArgument<DB.Param<"Content", DB.Type>>, true>;
318
318
  reduced: DB.MemberDecl<DB.TypeArgument<DB.Param<"Content", DB.Type>>, false>;
319
+ additonal: DB.MemberDecl<DB.String, false>;
319
320
  }>, [Content: DB.Param<"Content", DB.Type>]>>, true>;
320
321
  value: DB.MemberDecl<DB.Integer, false>;
321
322
  cost: DB.MemberDecl<DB.IncludeIdentifier<[], DB.Enum<"PoisonCost", {
@@ -394,6 +395,7 @@ export declare const Poison: DB.Entity<"Poison", {
394
395
  effect: DB.MemberDecl<DB.IncludeIdentifier<DB.Param<string, DB.Type>[], DB.TypeAlias<"Reduceable", DB.Object<{
395
396
  default: DB.MemberDecl<DB.TypeArgument<DB.Param<"Content", DB.Type>>, true>;
396
397
  reduced: DB.MemberDecl<DB.TypeArgument<DB.Param<"Content", DB.Type>>, false>;
398
+ additonal: DB.MemberDecl<DB.String, false>;
397
399
  }>, [Content: DB.Param<"Content", DB.Type>]>>, true>;
398
400
  notes: DB.MemberDecl<DB.String, false>;
399
401
  errata: DB.MemberDecl<DB.IncludeIdentifier<[], DB.TypeAlias<"Errata", DB.Array<DB.IncludeIdentifier<[], DB.TypeAlias<"Erratum", DB.Object<{
@@ -429,6 +431,7 @@ export declare const ExpressionBasedPoisonTimeExpressionValue: DB.Enum<"Expressi
429
431
  sides: DB.MemberDecl<DB.IncludeIdentifier<[], DB.TypeAlias<"DieType", DB.Integer, []>>, true>;
430
432
  }>, []>>>;
431
433
  CircleOfDamnation: DB.EnumCase<null>;
434
+ QualityLevels: DB.EnumCase<null>;
432
435
  }, []>;
433
436
  export declare const IndefinitePoisonTime: DB.TypeAlias<"IndefinitePoisonTime", DB.Object<{
434
437
  translations: DB.MemberDecl<DB.NestedEntityMap<"IndefinitePoisonTimeTranslation", {
@@ -175,6 +175,7 @@ export const ExpressionBasedPoisonTimeExpressionValue = DB.Enum(import.meta.url,
175
175
  Constant: DB.EnumCase({ type: DB.Integer({ minimum: 1 }) }),
176
176
  Dice: DB.EnumCase({ type: DB.IncludeIdentifier(Dice) }),
177
177
  CircleOfDamnation: DB.EnumCase({ type: null }),
178
+ QualityLevels: DB.EnumCase({ type: null }),
178
179
  }),
179
180
  });
180
181
  const PoisonTimeUnit = DB.Enum(import.meta.url, {
@@ -18,6 +18,10 @@ export const BotanicRegion = DB.Entity(import.meta.url, {
18
18
  }),
19
19
  parentReferenceKey: "parent",
20
20
  instanceDisplayName: {},
21
+ instanceDisplayNameCustomizer: ({ instance, instanceDisplayName, instanceDisplayNameLocaleId, getDisplayNameForInstanceId, }) => ({
22
+ name: `${getDisplayNameForInstanceId("SubBiome", instance.parent)?.name ?? ""} — ${instanceDisplayName}`,
23
+ localeId: instanceDisplayNameLocaleId,
24
+ }),
21
25
  uniqueConstraints: [
22
26
  [
23
27
  {
@@ -22,10 +22,19 @@ export const SubBiome = DB.Entity(import.meta.url, {
22
22
  }),
23
23
  parentReferenceKey: "parent",
24
24
  instanceDisplayName: {},
25
+ instanceDisplayNameCustomizer: ({ instance, instanceDisplayName, instanceDisplayNameLocaleId, getDisplayNameForInstanceId, }) => ({
26
+ name: `${getDisplayNameForInstanceId("Biome", instance.parent)?.name ?? ""} — ${instanceDisplayName}`,
27
+ localeId: instanceDisplayNameLocaleId,
28
+ }),
25
29
  uniqueConstraints: [
26
- {
27
- entityMapKeyPath: "translations",
28
- keyPathInEntityMap: "name",
29
- },
30
+ [
31
+ {
32
+ keyPath: "parent",
33
+ },
34
+ {
35
+ entityMapKeyPath: "translations",
36
+ keyPathInEntityMap: "name",
37
+ },
38
+ ],
30
39
  ],
31
40
  });
@@ -134,6 +134,7 @@ export { SikaryanDrainSpecialAbility } from "./specialAbility/SikaryanDrainSpeci
134
134
  export { SkillStyleSpecialAbility } from "./specialAbility/SkillStyleSpecialAbility.js";
135
135
  export { CeremonialItemSpecialAbilityGroup } from "./specialAbility/sub/CeremonialItemSpecialAbilityGroup.js";
136
136
  export { Language } from "./specialAbility/sub/Language.js";
137
+ export { MagicalTraditionSubgroup } from "./specialAbility/sub/MagicalTraditionSubgroup.ts";
137
138
  export { Script } from "./specialAbility/sub/Script.js";
138
139
  export { TradeSecret } from "./specialAbility/sub/TradeSecret.js";
139
140
  export { VampiricGift } from "./specialAbility/VampiricGift.js";
@@ -134,6 +134,7 @@ export { SikaryanDrainSpecialAbility } from "./specialAbility/SikaryanDrainSpeci
134
134
  export { SkillStyleSpecialAbility } from "./specialAbility/SkillStyleSpecialAbility.js";
135
135
  export { CeremonialItemSpecialAbilityGroup } from "./specialAbility/sub/CeremonialItemSpecialAbilityGroup.js";
136
136
  export { Language } from "./specialAbility/sub/Language.js";
137
+ export { MagicalTraditionSubgroup } from "./specialAbility/sub/MagicalTraditionSubgroup.js";
137
138
  export { Script } from "./specialAbility/sub/Script.js";
138
139
  export { TradeSecret } from "./specialAbility/sub/TradeSecret.js";
139
140
  export { VampiricGift } from "./specialAbility/VampiricGift.js";
@@ -1134,6 +1134,12 @@ export declare const MagicalTradition: DB.Entity<"MagicalTradition", {
1134
1134
  is_magical_dilettante: DB.MemberDecl<DB.Boolean, true>;
1135
1135
  use_arcane_spellworks_from_tradition: DB.MemberDecl<DB.ReferenceIdentifier, false>;
1136
1136
  influences: DB.MemberDecl<DB.Array<DB.ReferenceIdentifier>, false>;
1137
+ subgroups: DB.MemberDecl<DB.ChildEntities<DB.Entity<"MagicalTraditionSubgroup", {
1138
+ parent: DB.MemberDecl<DB.ReferenceIdentifier, true>;
1139
+ translations: DB.MemberDecl<DB.NestedEntityMap<"MagicalTraditionSubgroupTranslation", {
1140
+ name: DB.MemberDecl<DB.String, true>;
1141
+ }>, true>;
1142
+ }, "parent">>, true>;
1137
1143
  prerequisites: DB.MemberDecl<DB.IncludeIdentifier<[], DB.TypeAlias<"GeneralPrerequisites", DB.IncludeIdentifier<DB.Param<string, DB.Type>[], DB.TypeAlias<"PrerequisitesForLevels", DB.Array<DB.IncludeIdentifier<DB.Param<string, DB.Type>[], DB.TypeAlias<"PrerequisiteForLevel", DB.Object<{
1138
1144
  level: DB.MemberDecl<DB.Integer, true>;
1139
1145
  prerequisite: DB.MemberDecl<DB.IncludeIdentifier<DB.Param<string, DB.Type>[], DB.Enum<"PrerequisitesElement", {
@@ -10,6 +10,7 @@ import { NestedTranslationMap } from "../Locale.js";
10
10
  import { Errata } from "../source/_Erratum.js";
11
11
  import { src } from "../source/_PublicationRef.js";
12
12
  import { SpecialRule } from "./_Tradition.js";
13
+ import { MagicalTraditionSubgroup } from "./sub/MagicalTraditionSubgroup.js";
13
14
  export const MagicalTradition = DB.Entity(import.meta.url, {
14
15
  name: "MagicalTradition",
15
16
  namePlural: "MagicalTraditions",
@@ -61,9 +62,13 @@ export const MagicalTradition = DB.Entity(import.meta.url, {
61
62
  type: MagicalTraditionIdentifier(),
62
63
  }),
63
64
  influences: DB.Optional({
64
- comment: "The influences for the traditions. Influences are enabled by Focus Rules.",
65
+ comment: "The influences for the tradition. Influences are enabled by Focus Rules.",
65
66
  type: DB.Array(InfluenceIdentifier(), { minItems: 2 }),
66
67
  }),
68
+ subgroups: DB.Required({
69
+ comment: "The subgroups of this tradition.",
70
+ type: DB.ChildEntities(MagicalTraditionSubgroup),
71
+ }),
67
72
  prerequisites: DB.Optional({
68
73
  type: DB.IncludeIdentifier(GeneralPrerequisites),
69
74
  }),
@@ -0,0 +1,7 @@
1
+ import * as DB from "tsondb/schema/dsl";
2
+ export declare const MagicalTraditionSubgroup: DB.Entity<"MagicalTraditionSubgroup", {
3
+ parent: DB.MemberDecl<DB.ReferenceIdentifier, true>;
4
+ translations: DB.MemberDecl<DB.NestedEntityMap<"MagicalTraditionSubgroupTranslation", {
5
+ name: DB.MemberDecl<DB.String, true>;
6
+ }>, true>;
7
+ }, "parent">;
@@ -0,0 +1,27 @@
1
+ import * as DB from "tsondb/schema/dsl";
2
+ import { NestedTranslationMap } from "../../Locale.js";
3
+ import { MagicalTraditionIdentifier } from "../../_Identifier.js";
4
+ export const MagicalTraditionSubgroup = DB.Entity(import.meta.url, {
5
+ name: "MagicalTraditionSubgroup",
6
+ namePlural: "MagicalTraditionSubgroups",
7
+ type: () => DB.Object({
8
+ parent: DB.Required({
9
+ comment: "The magical tradition this subgroup belongs to.",
10
+ type: MagicalTraditionIdentifier(),
11
+ }),
12
+ translations: NestedTranslationMap(DB.Required, "MagicalTraditionSubgroup", DB.Object({
13
+ name: DB.Required({
14
+ comment: "The name of the ceremonial item. This should be the heading used in the respective publication.",
15
+ type: DB.String({ minLength: 1 }),
16
+ }),
17
+ })),
18
+ }),
19
+ parentReferenceKey: "parent",
20
+ instanceDisplayName: {},
21
+ uniqueConstraints: [
22
+ {
23
+ entityMapKeyPath: "translations",
24
+ keyPathInEntityMap: "name",
25
+ },
26
+ ],
27
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@optolith/database-schema",
3
- "version": "0.82.0",
3
+ "version": "0.84.0",
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",