@datasworn-community/build-tools 0.2.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.
Files changed (134) hide show
  1. package/README.md +17 -0
  2. package/dist/cli/args.d.ts +3 -0
  3. package/dist/cli/args.d.ts.map +1 -0
  4. package/dist/cli/args.js +10 -0
  5. package/dist/cli/args.js.map +1 -0
  6. package/dist/cli/datasworn-build.d.ts +3 -0
  7. package/dist/cli/datasworn-build.d.ts.map +1 -0
  8. package/dist/cli/datasworn-build.js +33 -0
  9. package/dist/cli/datasworn-build.js.map +1 -0
  10. package/dist/cli/datasworn-migrate.d.ts +3 -0
  11. package/dist/cli/datasworn-migrate.d.ts.map +1 -0
  12. package/dist/cli/datasworn-migrate.js +26 -0
  13. package/dist/cli/datasworn-migrate.js.map +1 -0
  14. package/dist/config.d.ts +3 -0
  15. package/dist/config.d.ts.map +1 -0
  16. package/dist/config.js +10 -0
  17. package/dist/config.js.map +1 -0
  18. package/dist/index.d.ts +4 -0
  19. package/dist/index.d.ts.map +1 -0
  20. package/dist/index.js +4 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/rules-package-builder.d.ts +22 -0
  23. package/dist/rules-package-builder.d.ts.map +1 -0
  24. package/dist/rules-package-builder.js +84 -0
  25. package/dist/rules-package-builder.js.map +1 -0
  26. package/dist/schema.d.ts +8 -0
  27. package/dist/schema.d.ts.map +1 -0
  28. package/dist/schema.js +18 -0
  29. package/dist/schema.js.map +1 -0
  30. package/dist/validators.d.ts +8 -0
  31. package/dist/validators.d.ts.map +1 -0
  32. package/dist/validators.js +35 -0
  33. package/dist/validators.js.map +1 -0
  34. package/package.json +60 -0
  35. package/schema-source/schema/Assets.ts +66 -0
  36. package/schema-source/schema/Atlas.ts +20 -0
  37. package/schema-source/schema/Defs.ts +126 -0
  38. package/schema-source/schema/DelveSites.ts +3 -0
  39. package/schema-source/schema/Entities.ts +1 -0
  40. package/schema-source/schema/Generic.ts +18 -0
  41. package/schema-source/schema/Moves.ts +1 -0
  42. package/schema-source/schema/Npcs.ts +80 -0
  43. package/schema-source/schema/Oracles.ts +20 -0
  44. package/schema-source/schema/Rarities.ts +36 -0
  45. package/schema-source/schema/Root.ts +94 -0
  46. package/schema-source/schema/Rules.ts +61 -0
  47. package/schema-source/schema/RulesPackages.ts +135 -0
  48. package/schema-source/schema/Symbols.ts +30 -0
  49. package/schema-source/schema/Truths.ts +53 -0
  50. package/schema-source/schema/Utils.ts +21 -0
  51. package/schema-source/schema/assets/Ability.ts +79 -0
  52. package/schema-source/schema/assets/Enhancement.ts +62 -0
  53. package/schema-source/schema/assets/Fields.ts +285 -0
  54. package/schema-source/schema/assets/common.ts +29 -0
  55. package/schema-source/schema/common/Fields.ts +327 -0
  56. package/schema-source/schema/common/Id.ts +64 -0
  57. package/schema-source/schema/common/Inputs.ts +374 -0
  58. package/schema-source/schema/common/Metadata.ts +142 -0
  59. package/schema-source/schema/common/Player.ts +17 -0
  60. package/schema-source/schema/common/Progress.ts +63 -0
  61. package/schema-source/schema/common/Range.ts +53 -0
  62. package/schema-source/schema/common/RollableValues.ts +152 -0
  63. package/schema-source/schema/common/Rolls.ts +108 -0
  64. package/schema-source/schema/common/Text.ts +95 -0
  65. package/schema-source/schema/common/index.ts +16 -0
  66. package/schema-source/schema/delve/DelveSite.ts +121 -0
  67. package/schema-source/schema/delve/DelveSiteDomain.ts +136 -0
  68. package/schema-source/schema/delve/DelveSiteTheme.ts +97 -0
  69. package/schema-source/schema/delve/common.ts +32 -0
  70. package/schema-source/schema/entities/EntityPrompt.ts +13 -0
  71. package/schema-source/schema/entities/index.ts +1 -0
  72. package/schema-source/schema/generic/CollectableNode.ts +75 -0
  73. package/schema-source/schema/generic/CollectionNode.ts +145 -0
  74. package/schema-source/schema/generic/Dictionary.ts +39 -0
  75. package/schema-source/schema/generic/EmbedOnlyNode.ts +19 -0
  76. package/schema-source/schema/generic/Enhance.ts +38 -0
  77. package/schema-source/schema/generic/IdNode.ts +40 -0
  78. package/schema-source/schema/generic/Mixin.ts +11 -0
  79. package/schema-source/schema/generic/NonCollectableNode.ts +38 -0
  80. package/schema-source/schema/generic/PrimaryTypeNode.ts +115 -0
  81. package/schema-source/schema/generic/SourcedNode.ts +51 -0
  82. package/schema-source/schema/index.ts +23 -0
  83. package/schema-source/schema/moves/ActionRoll.ts +152 -0
  84. package/schema-source/schema/moves/EmbeddedMove.ts +24 -0
  85. package/schema-source/schema/moves/Move.ts +26 -0
  86. package/schema-source/schema/moves/MoveCategory.ts +6 -0
  87. package/schema-source/schema/moves/MoveEnhancement.ts +29 -0
  88. package/schema-source/schema/moves/ProgressRoll.ts +184 -0
  89. package/schema-source/schema/moves/Trigger.ts +193 -0
  90. package/schema-source/schema/moves/common.ts +136 -0
  91. package/schema-source/schema/moves/index.ts +13 -0
  92. package/schema-source/schema/moves/utils.ts +132 -0
  93. package/schema-source/schema/object_type/ObjectType.ts +23 -0
  94. package/schema-source/schema/oracles/EmbeddedOracleRollable.ts +28 -0
  95. package/schema-source/schema/oracles/OracleCollection.ts +140 -0
  96. package/schema-source/schema/oracles/OracleRollable.ts +207 -0
  97. package/schema-source/schema/oracles/Table.ts +94 -0
  98. package/schema-source/schema/oracles/TableRow.ts +141 -0
  99. package/schema-source/schema/root/NiceSchema.ts +15 -0
  100. package/schema-source/schema/root/Root.ts +41 -0
  101. package/schema-source/schema/root/SchemaTransform.ts +89 -0
  102. package/schema-source/schema/root/SourceData.ts +151 -0
  103. package/schema-source/schema/rules/ConditionMeterRule.ts +25 -0
  104. package/schema-source/schema/rules/ImpactRule.ts +54 -0
  105. package/schema-source/schema/rules/SpecialTrackRule.ts +29 -0
  106. package/schema-source/schema/rules/StatRule.ts +23 -0
  107. package/schema-source/schema/rules/TagRule.ts +176 -0
  108. package/schema-source/schema/rules/TagSchema.ts +161 -0
  109. package/schema-source/schema/tags/canonicalTags.ts +29 -0
  110. package/schema-source/schema/tools/build/index.ts +48 -0
  111. package/schema-source/schema/tools/i18n/index.ts +9 -0
  112. package/schema-source/schema/utils/Computed.ts +82 -0
  113. package/schema-source/schema/utils/DiscriminatedUnion.ts +255 -0
  114. package/schema-source/schema/utils/EmbeddedNode.ts +172 -0
  115. package/schema-source/schema/utils/ExtractLiteralFromEnum.ts +22 -0
  116. package/schema-source/schema/utils/FlatIntersect.ts +107 -0
  117. package/schema-source/schema/utils/IfThen.ts +50 -0
  118. package/schema-source/schema/utils/MergeEnumSchemas.ts +16 -0
  119. package/schema-source/schema/utils/NonNullable.ts +6 -0
  120. package/schema-source/schema/utils/Nullable.ts +29 -0
  121. package/schema-source/schema/utils/ObjectLiteral.ts +16 -0
  122. package/schema-source/schema/utils/ObjectProperties.ts +4 -0
  123. package/schema-source/schema/utils/OmitMeta.ts +22 -0
  124. package/schema-source/schema/utils/OmitOptional.ts +27 -0
  125. package/schema-source/schema/utils/PartialExcept.ts +26 -0
  126. package/schema-source/schema/utils/SetNullable.ts +44 -0
  127. package/schema-source/schema/utils/SetOptional.ts +48 -0
  128. package/schema-source/schema/utils/UnionEnum.ts +82 -0
  129. package/schema-source/schema/utils/UnionEnumFromRecord.ts +36 -0
  130. package/schema-source/schema/utils/UnionOneOf.ts +80 -0
  131. package/schema-source/schema/utils/generateRulesetSchemas.ts +204 -0
  132. package/schema-source/schema/utils/string.ts +15 -0
  133. package/schema-source/schema/utils/typebox.ts +141 -0
  134. package/schema-source/scripts/const.ts +55 -0
@@ -0,0 +1,51 @@
1
+ import {
2
+ type ObjectOptions,
3
+ type Static,
4
+ type TObject,
5
+ Type
6
+ } from '@sinclair/typebox'
7
+ import type { TAnyId } from '../common/Id.js'
8
+ import { SourceInfo, Suggestions } from '../common/Metadata.js'
9
+ import { Label } from '../common/Text.js'
10
+ import { Tags } from '../rules/TagRule.js'
11
+ import { FlatIntersect, type TAssign } from '../utils/FlatIntersect.js'
12
+ import { IdNode, type TIdNode } from './IdNode.js'
13
+
14
+ export const SourcedNodeBase = Type.Object({
15
+ name: Type.Ref(Label, {
16
+ description: 'The primary name/label for this node.'
17
+ }),
18
+ canonical_name: Type.Optional(
19
+ Type.Ref(Label, {
20
+ description:
21
+ "The name of this node as it appears on the page in the book, if it's different from `name`."
22
+ })
23
+ ),
24
+ _source: Type.Ref(SourceInfo, {
25
+ description:
26
+ 'Attribution for the original source (such as a book or website) of this node, including the author and licensing information.'
27
+ }),
28
+ suggestions: Type.Optional(Type.Ref(Suggestions)),
29
+ tags: Type.Optional(Type.Ref(Tags))
30
+ })
31
+
32
+ /** Interface shared by objects with source attribute. */
33
+
34
+ export function SourcedNode<TBase extends TObject>(
35
+ base: TBase,
36
+ _id: TAnyId,
37
+ options: ObjectOptions = {}
38
+ ) {
39
+ const enhancedBase = FlatIntersect([SourcedNodeBase, base])
40
+
41
+ return IdNode(enhancedBase, _id, options)
42
+ }
43
+
44
+ export type TSourcedNode<TBase extends TObject> = TIdNode<
45
+ TAssign<typeof SourcedNodeBase, TBase>
46
+ > & { static: SourcedNode<Static<TBase>> }
47
+
48
+ export type SourcedNode<TBase extends object = object> = Static<
49
+ typeof SourcedNodeBase
50
+ > &
51
+ IdNode<TBase>
@@ -0,0 +1,23 @@
1
+ /**
2
+ * TypeBox JSON schema, with annotations so they can be converted to JSON TypeDef.
3
+ */
4
+
5
+ // depends on moves, oracles
6
+ export * from './Assets.js'
7
+ // no/few dependencies
8
+ export * from './Atlas.js'
9
+ export * from './common/index.js'
10
+ export * from './Defs.js'
11
+ // delve stuff
12
+ export * from './DelveSites.js'
13
+ // depends on oracles
14
+ export * from './Entities.js'
15
+ export * from './Generic.js'
16
+ export * from './Moves.js'
17
+ export * from './Npcs.js'
18
+ export * from './Oracles.js'
19
+ export * from './Rarities.js'
20
+ export * from './Root.js'
21
+ export * from './Rules.js'
22
+ export * from './RulesPackages.js'
23
+ export * from './Truths.js'
@@ -0,0 +1,152 @@
1
+ import { type Static, Type } from '@sinclair/typebox'
2
+ import { RollableValue } from '../common/RollableValues.js'
3
+ import {
4
+ ActionRollMethod,
5
+ MoveOutcomes,
6
+ type MoveOutcomes as MoveOutcomesType
7
+ } from './common.js'
8
+ import {
9
+ Trigger,
10
+ TriggerCondition,
11
+ TriggerConditionEnhancement,
12
+ TriggerEnhancement
13
+ } from './Trigger.js'
14
+ import { Move, MoveEnhancement } from './utils.js'
15
+
16
+ export const TriggerActionRollCondition = TriggerCondition(
17
+ Type.Ref(ActionRollMethod),
18
+ Type.Array(Type.Ref(RollableValue)),
19
+ { $id: 'TriggerActionRollCondition', title: 'TriggerActionRollCondition' }
20
+ )
21
+ export type TriggerActionRollCondition = Static<
22
+ typeof TriggerActionRollCondition
23
+ >
24
+
25
+ export const TriggerActionRoll = Trigger(
26
+ Type.Array(Type.Ref(TriggerActionRollCondition)),
27
+ {
28
+ $id: 'TriggerActionRoll',
29
+ title: 'TriggerActionRoll',
30
+ description:
31
+ 'Describes trigger conditions for a move that makes an action roll.'
32
+ }
33
+ )
34
+ export type TriggerActionRoll = Static<typeof TriggerActionRoll>
35
+
36
+ export const MoveActionRoll = Move(
37
+ 'action_roll',
38
+ Type.Ref(TriggerActionRoll),
39
+ Type.Ref(MoveOutcomes),
40
+ {
41
+ title: 'Move (action roll)',
42
+ description: 'A move that makes an action roll.',
43
+ $id: 'MoveActionRoll'
44
+ }
45
+ )
46
+
47
+ export type MoveActionRoll = Move<
48
+ 'action_roll',
49
+ TriggerActionRoll,
50
+ MoveOutcomesType
51
+ >
52
+
53
+ export const TriggerActionRollConditionEnhancement =
54
+ TriggerConditionEnhancement(TriggerActionRollCondition, {
55
+ $id: 'TriggerActionRollConditionEnhancement',
56
+ title: 'TriggerActionRollConditionEnhancement'
57
+ })
58
+
59
+ export type TriggerActionRollConditionEnhancement = Static<
60
+ typeof TriggerActionRollConditionEnhancement
61
+ >
62
+
63
+ export const TriggerActionRollEnhancement = TriggerEnhancement(
64
+ Type.Array(Type.Ref(TriggerActionRollConditionEnhancement)),
65
+ {
66
+ $id: 'TriggerActionRollEnhancement',
67
+ title: 'TriggerActionRollEnhancement'
68
+ }
69
+ )
70
+ export type TriggerActionRollEnhancement = Static<
71
+ typeof TriggerActionRollEnhancement
72
+ >
73
+
74
+ // TRIGGER: NO ROLL
75
+
76
+ export const TriggerNoRollCondition = TriggerCondition(
77
+ Type.Null({ default: null }),
78
+ Type.Null({ default: null }),
79
+ { $id: 'TriggerNoRollCondition', title: 'TriggerNoRollCondition' }
80
+ )
81
+
82
+ export type TriggerNoRollCondition = Static<typeof TriggerNoRollCondition>
83
+
84
+ export const TriggerNoRoll = Trigger(
85
+ Type.Array(Type.Ref(TriggerNoRollCondition), {
86
+ default: []
87
+ }),
88
+ {
89
+ $id: 'TriggerNoRoll',
90
+ title: 'TriggerNoRoll',
91
+ description: 'Describes trigger conditions for a move that makes no rolls.'
92
+ }
93
+ )
94
+
95
+ export type TriggerNoRoll = Static<typeof TriggerNoRoll>
96
+
97
+ export const MoveNoRoll = Move(
98
+ 'no_roll',
99
+ Type.Ref(TriggerNoRoll),
100
+ Type.Null({ default: null }),
101
+ {
102
+ $id: 'MoveNoRoll',
103
+ description: 'A move that makes no progress rolls or action rolls.'
104
+ }
105
+ )
106
+
107
+ export type MoveNoRoll = Static<typeof MoveNoRoll>
108
+
109
+ // No-roll triggers need a separate enhancement condition type to exclude _id
110
+ export const TriggerNoRollConditionEnhancement = TriggerConditionEnhancement(
111
+ TriggerNoRollCondition,
112
+ {
113
+ $id: 'TriggerNoRollConditionEnhancement',
114
+ title: 'TriggerNoRollConditionEnhancement'
115
+ }
116
+ )
117
+ export type TriggerNoRollConditionEnhancement = Static<
118
+ typeof TriggerNoRollConditionEnhancement
119
+ >
120
+
121
+ export const TriggerNoRollEnhancement = TriggerEnhancement(
122
+ Type.Array(Type.Ref(TriggerNoRollConditionEnhancement)),
123
+ {
124
+ $id: 'TriggerNoRollEnhancement',
125
+ title: 'TriggerNoRollEnhancement'
126
+ }
127
+ )
128
+ export type TriggerNoRollEnhancement = Static<typeof TriggerNoRollEnhancement>
129
+
130
+ export const MoveNoRollEnhancement = MoveEnhancement(
131
+ 'no_roll',
132
+ Type.Ref(TriggerNoRollEnhancement),
133
+ {
134
+ $id: 'MoveNoRollEnhancement'
135
+ }
136
+ )
137
+ export type MoveNoRollEnhancement = MoveEnhancement<
138
+ 'no_roll',
139
+ TriggerNoRollEnhancement
140
+ >
141
+
142
+ export const MoveActionRollEnhancement = MoveEnhancement(
143
+ 'action_roll',
144
+ Type.Ref(TriggerActionRollEnhancement),
145
+ {
146
+ $id: 'MoveActionRollEnhancement'
147
+ }
148
+ )
149
+ export type MoveActionRollEnhancement = MoveEnhancement<
150
+ 'action_roll',
151
+ TriggerActionRollEnhancement
152
+ >
@@ -0,0 +1,24 @@
1
+ import type { Static } from '@sinclair/typebox'
2
+ import { mapValues } from 'lodash-es'
3
+ import { Mapping } from '../Symbols.js'
4
+ import { DiscriminatedUnion } from '../Utils.js'
5
+ import { EmbeddedPrimaryNode } from '../utils/EmbeddedNode.js'
6
+ import { pascalCase } from '../utils/string.js'
7
+ import { Move } from './Move.js'
8
+
9
+ const moveMapping = mapValues(Move[Mapping], (schema, k) =>
10
+ EmbeddedPrimaryNode(schema, [], { $id: `Embedded${pascalCase(k)}Move` })
11
+ )
12
+
13
+ export const {
14
+ action_roll: EmbeddedActionRollMove,
15
+ no_roll: EmbeddedNoRollMove,
16
+ progress_roll: EmbeddedProgressRollMove,
17
+ special_track: EmbeddedSpecialTrackMove
18
+ } = moveMapping
19
+
20
+ export const EmbeddedMove = DiscriminatedUnion(moveMapping, 'roll_type', {
21
+ $id: 'EmbeddedMove'
22
+ })
23
+
24
+ export type EmbeddedMove = Static<typeof EmbeddedMove>
@@ -0,0 +1,26 @@
1
+ import * as Utils from '../Utils.js'
2
+ import { MoveActionRoll, MoveNoRoll } from './ActionRoll.js'
3
+ import { MoveProgressRoll, MoveSpecialTrack } from './ProgressRoll.js'
4
+ import { moveDiscriminator } from './utils.js'
5
+
6
+ // discriminated union of all moves
7
+
8
+ export const Move = Utils.DiscriminatedUnion(
9
+ {
10
+ action_roll: MoveActionRoll,
11
+ no_roll: MoveNoRoll,
12
+ progress_roll: MoveProgressRoll,
13
+ special_track: MoveSpecialTrack
14
+ },
15
+ moveDiscriminator,
16
+ {
17
+ $id: 'Move',
18
+ title: 'Move'
19
+ }
20
+ )
21
+
22
+ export type Move =
23
+ | MoveActionRoll
24
+ | MoveNoRoll
25
+ | MoveProgressRoll
26
+ | MoveSpecialTrack
@@ -0,0 +1,6 @@
1
+ import { type Static, Type } from '@sinclair/typebox'
2
+ import { CollectionNode } from '../generic/CollectionNode.js'
3
+
4
+ export const MoveCategory = CollectionNode(Type.Object({}), 'move_category')
5
+ export type MoveCategory = Static<typeof MoveCategory>
6
+ export type TMoveCategory = typeof MoveCategory
@@ -0,0 +1,29 @@
1
+ import * as Utils from '../Utils.js'
2
+ import {
3
+ MoveActionRollEnhancement,
4
+ MoveNoRollEnhancement
5
+ } from './ActionRoll.js'
6
+ import {
7
+ MoveProgressRollEnhancement,
8
+ MoveSpecialTrackEnhancement
9
+ } from './ProgressRoll.js'
10
+ import { moveDiscriminator } from './utils.js'
11
+
12
+ export const MoveEnhancement = Utils.DiscriminatedUnion(
13
+ {
14
+ action_roll: MoveActionRollEnhancement,
15
+ no_roll: MoveNoRollEnhancement,
16
+ progress_roll: MoveProgressRollEnhancement,
17
+ special_track: MoveSpecialTrackEnhancement
18
+ },
19
+ moveDiscriminator,
20
+ {
21
+ $id: 'MoveEnhancement'
22
+ }
23
+ )
24
+ export type TMoveEnhancement = typeof MoveEnhancement
25
+ export type MoveEnhancement =
26
+ | MoveNoRollEnhancement
27
+ | MoveActionRollEnhancement
28
+ | MoveProgressRollEnhancement
29
+ | MoveSpecialTrackEnhancement
@@ -0,0 +1,184 @@
1
+ import { type Static, Type } from '@sinclair/typebox'
2
+ import * as Progress from '../common/Progress.js'
3
+ import { Assign } from '../utils/FlatIntersect.js'
4
+ import {
5
+ Trigger,
6
+ TriggerCondition,
7
+ TriggerConditionEnhancement,
8
+ TriggerEnhancement
9
+ } from './Trigger.js'
10
+ import { Move, MoveEnhancement } from './utils.js'
11
+
12
+ export const ProgressRollOption = Type.Object(
13
+ {
14
+ using: Type.Literal('progress_track')
15
+ },
16
+ { $id: 'ProgressRollOption' }
17
+ )
18
+ export type ProgressRollOption = Static<typeof ProgressRollOption>
19
+
20
+ export const TriggerProgressRollCondition = TriggerCondition(
21
+ Type.Ref('ProgressRollMethod', {
22
+ default: 'progress_roll'
23
+ }),
24
+ Type.Array(Type.Ref('ProgressRollOption')),
25
+ {
26
+ $id: 'TriggerProgressRollCondition',
27
+ title: 'TriggerProgressRollCondition'
28
+ }
29
+ )
30
+
31
+ export type TriggerProgressRollCondition = Static<
32
+ typeof TriggerProgressRollCondition
33
+ >
34
+
35
+ export const TriggerProgressRoll = Trigger(
36
+ Type.Array(Type.Ref(TriggerProgressRollCondition)),
37
+ {
38
+ $id: 'TriggerProgressRoll',
39
+ title: 'TriggerProgressRoll'
40
+ }
41
+ )
42
+
43
+ export type TriggerProgressRoll = Static<typeof TriggerProgressRoll>
44
+
45
+ export const MoveProgressRoll = Assign(
46
+ Move(
47
+ 'progress_roll',
48
+ Type.Ref('TriggerProgressRoll'),
49
+ Type.Ref('MoveOutcomes'),
50
+ { $id: 'MoveProgressRollBase' }
51
+ ),
52
+ Type.Object({
53
+ // is_progress_move: Type.Literal(true, { default: true }),
54
+ tracks: Type.Ref(Progress.ProgressTrackTypeInfo, {
55
+ description:
56
+ 'Describes the common features of progress tracks associated with this move.'
57
+ })
58
+ }),
59
+ {
60
+ title: 'Progress Move',
61
+ description:
62
+ 'A progress move that rolls on a standard progress track type (whose features are defined by this move object). For progress rolls that use special tracks, see MoveSpecialTrack.',
63
+ $id: 'MoveProgressRoll'
64
+ }
65
+ )
66
+
67
+ export type MoveProgressRoll = Static<typeof MoveProgressRoll>
68
+
69
+ // AUGMENTS
70
+
71
+ export const TriggerProgressRollConditionEnhancement =
72
+ TriggerConditionEnhancement(TriggerProgressRollCondition, {
73
+ $id: 'TriggerProgressRollConditionEnhancement',
74
+ title: 'TriggerProgressRollConditionEnhancement'
75
+ })
76
+ export type TriggerProgressRollConditionEnhancement = Static<
77
+ typeof TriggerProgressRollConditionEnhancement
78
+ >
79
+
80
+ export const TriggerProgressRollEnhancement = TriggerEnhancement(
81
+ Type.Array(Type.Ref('TriggerProgressRollConditionEnhancement')),
82
+ {
83
+ $id: 'TriggerProgressRollEnhancement',
84
+ title: 'TriggerProgressRollEnhancement'
85
+ }
86
+ )
87
+ export type TriggerProgressRollEnhancement = Static<
88
+ typeof TriggerProgressRollEnhancement
89
+ >
90
+
91
+ export const MoveProgressRollEnhancement = MoveEnhancement(
92
+ 'progress_roll',
93
+ Type.Ref(TriggerProgressRollEnhancement),
94
+ {
95
+ $id: 'MoveProgressRollEnhancement'
96
+ }
97
+ )
98
+ export type MoveProgressRollEnhancement = Static<
99
+ typeof MoveProgressRollEnhancement
100
+ >
101
+
102
+ // SPECIAL TRACK
103
+
104
+ export const TriggerSpecialTrackConditionOption = Type.Object(
105
+ {
106
+ using: Type.Ref('SpecialTrackType')
107
+ },
108
+ {
109
+ $id: 'TriggerSpecialTrackConditionOption',
110
+ title: 'TriggerSpecialTrackConditionOption'
111
+ }
112
+ )
113
+ export type TriggerSpecialTrackConditionOption = Static<
114
+ typeof TriggerSpecialTrackConditionOption
115
+ >
116
+
117
+ export const TriggerSpecialTrackCondition = TriggerCondition(
118
+ Type.Ref('SpecialTrackRollMethod'),
119
+ Type.Array(Type.Ref('TriggerSpecialTrackConditionOption')),
120
+ {
121
+ $id: 'TriggerSpecialTrackCondition',
122
+ title: 'TriggerSpecialTrackCondition'
123
+ }
124
+ )
125
+ export type TriggerSpecialTrackCondition = Static<
126
+ typeof TriggerSpecialTrackCondition
127
+ >
128
+
129
+ export const TriggerSpecialTrack = Trigger(
130
+ Type.Array(Type.Ref(TriggerSpecialTrackCondition)),
131
+ {
132
+ $id: 'TriggerSpecialTrack',
133
+ title: 'TriggerSpecialTrack'
134
+ }
135
+ )
136
+
137
+ export type TriggerSpecialTrack = Static<typeof TriggerSpecialTrack>
138
+
139
+ export const MoveSpecialTrack = Move(
140
+ 'special_track',
141
+ // is_progress_move: Type.Literal(true, { default: true }),
142
+ Type.Ref('TriggerSpecialTrack'),
143
+ Type.Ref('MoveOutcomes'),
144
+
145
+ {
146
+ title: 'Progress Move (special track roll)',
147
+ $id: 'MoveSpecialTrack',
148
+ description:
149
+ 'A progress move that rolls on a special track, such as Legacies (Starforged) or Bonds (classic Ironsworn). For progress moves that use standard progress tracks, see MoveProgressRoll instead.'
150
+ }
151
+ )
152
+
153
+ export type MoveSpecialTrack = Static<typeof MoveSpecialTrack>
154
+
155
+ export const TriggerSpecialTrackConditionEnhancement =
156
+ TriggerConditionEnhancement(TriggerSpecialTrackCondition, {
157
+ $id: 'TriggerSpecialTrackConditionEnhancement',
158
+ title: 'TriggerSpecialTrackConditionEnhancement',
159
+ description:
160
+ 'A progress move that rolls on one or more special tracks, like Bonds (classic Ironsworn), Failure (Delve), or Legacy (Starforged).'
161
+ })
162
+ export type TriggerSpecialTrackConditionEnhancement = Static<
163
+ typeof TriggerSpecialTrackConditionEnhancement
164
+ >
165
+
166
+ export const TriggerSpecialTrackEnhancement = TriggerEnhancement(
167
+ Type.Array(Type.Ref('TriggerSpecialTrackConditionEnhancement')),
168
+ {
169
+ $id: 'TriggerSpecialTrackEnhancement',
170
+ title: 'TriggerSpecialTrackEnhancement'
171
+ }
172
+ )
173
+ export type TriggerSpecialTrackEnhancement = TriggerEnhancement<any>
174
+
175
+ export const MoveSpecialTrackEnhancement = MoveEnhancement(
176
+ 'special_track',
177
+ Type.Ref(TriggerSpecialTrackEnhancement),
178
+ {
179
+ $id: 'MoveSpecialTrackEnhancement'
180
+ }
181
+ )
182
+ export type MoveSpecialTrackEnhancement = Static<
183
+ typeof MoveSpecialTrackEnhancement
184
+ >
@@ -0,0 +1,193 @@
1
+ import {
2
+ type ObjectOptions,
3
+ type Static,
4
+ type TArray,
5
+ type TNull,
6
+ type TObject,
7
+ type TSchema,
8
+ Type,
9
+ TypeGuard
10
+ } from '@sinclair/typebox'
11
+ import * as Text from '../common/Text.js'
12
+ import * as Utils from '../Utils.js'
13
+ import { Assign } from '../utils/FlatIntersect.js'
14
+ import {
15
+ setDescriptions,
16
+ type TFuzzyNull,
17
+ type TFuzzyObject,
18
+ type TFuzzyRef
19
+ } from '../utils/typebox.js'
20
+
21
+ export const TriggerBy = Type.Object(
22
+ {
23
+ player: Type.Boolean({
24
+ default: true,
25
+ description: 'Can this trigger be activated by the player who owns this?'
26
+ }),
27
+ ally: Type.Boolean({
28
+ default: false,
29
+ description:
30
+ "Can this trigger be activated by one of the player's allies?"
31
+ })
32
+ },
33
+ {
34
+ $id: 'TriggerBy',
35
+ title: 'TriggerBy',
36
+ description:
37
+ "Information on who can activate this trigger condition. Usually this is just the player, but some asset abilities can trigger from an ally's move."
38
+ }
39
+ )
40
+ export type TriggerBy = Static<typeof TriggerBy>
41
+
42
+ const TriggerConditionBase = Type.Object({
43
+ _id: Utils.Computed(Type.Ref('AnyMoveConditionId')),
44
+ text: Type.Optional(
45
+ Type.Ref(Text.MarkdownString, {
46
+ description:
47
+ 'A markdown string of any trigger text specific to this trigger condition.'
48
+ })
49
+ ),
50
+ by: Type.Optional(Type.Ref(TriggerBy))
51
+ })
52
+
53
+ export function TriggerCondition<
54
+ Method extends TFuzzyNull<Utils.TUnionEnum<string[]>>,
55
+ RollOptions extends TFuzzyNull<TArray<TFuzzyObject<{ using: TSchema }>>>
56
+ >(method: Method, rollOptions: RollOptions, options: ObjectOptions = {}) {
57
+ const roll_options: RollOptions = {
58
+ description:
59
+ 'The options available when rolling with this trigger condition.',
60
+ ...rollOptions
61
+ }
62
+ return Assign(
63
+ TriggerConditionBase,
64
+ Type.Object({
65
+ method,
66
+ roll_options
67
+ }),
68
+ options
69
+ )
70
+ }
71
+ export type TTriggerCondition<
72
+ Method extends TFuzzyNull<Utils.TUnionEnum<string[]>> = TFuzzyNull<
73
+ Utils.TUnionEnum<string[]>
74
+ >,
75
+ RollOptions extends TFuzzyNull<
76
+ TArray<TFuzzyObject<{ using: TSchema }>>
77
+ > = TFuzzyNull<TArray<TFuzzyObject<{ using: TSchema }>>>
78
+ > = ReturnType<typeof TriggerCondition<Method, RollOptions>>
79
+
80
+ export type TriggerCondition<
81
+ Method extends string | null = string | null,
82
+ RollOptions extends Array<{ using: any }> | null = Array<{
83
+ using: any
84
+ }> | null
85
+ > = { roll_options: RollOptions; method: Method }
86
+
87
+ export function TriggerConditionEnhancement<T extends TTriggerCondition>(
88
+ triggerCondition: T,
89
+ options: ObjectOptions
90
+ ) {
91
+ const RollOptions = Type.Index(triggerCondition, ['roll_options'])
92
+ type RollOptions = typeof RollOptions
93
+
94
+ const Method = Type.Index(triggerCondition, ['method'])
95
+
96
+ type TNullableRollOptions = Omit<
97
+ T['properties'],
98
+ 'roll_options' | 'method' | '_id'
99
+ > & {
100
+ roll_options: RollOptions extends TNull | Utils.TNullable
101
+ ? RollOptions
102
+ : Utils.TNullable<RollOptions>
103
+ method: typeof Method extends TNull | Utils.TNullable
104
+ ? typeof Method
105
+ : Utils.TNullable<typeof Method>
106
+ }
107
+
108
+ const rollOptionsAreNullable =
109
+ TypeGuard.IsNull(Method) ?? Utils.TNullable(Method)
110
+
111
+ const roll_options = rollOptionsAreNullable
112
+ ? RollOptions
113
+ : Utils.Nullable(RollOptions, { default: null })
114
+
115
+ const methodIsNullable = TypeGuard.IsNull(Method) ?? Utils.TNullable(Method)
116
+
117
+ const method = methodIsNullable
118
+ ? Method
119
+ : Utils.Nullable(Method, {
120
+ description:
121
+ 'A `null` value means this condition provides no roll mechanic of its own; it must be used with another trigger condition that provides a non-null `method`.',
122
+ default: null
123
+ })
124
+
125
+ // Exclude _id from enhancement conditions as they're nested within asset abilities
126
+ // and not directly assignable IDs in the current ID system
127
+ const { _id, ...baseProps } = triggerCondition.properties
128
+ const nuProps = {
129
+ ...baseProps,
130
+ roll_options,
131
+ method
132
+ } as TNullableRollOptions
133
+
134
+ // Cast to Record<string, TSchema> to avoid deep type instantiation
135
+ return Type.Object(nuProps as Record<string, TSchema>, options)
136
+ }
137
+
138
+ const TriggerMixin = Type.Object({
139
+ text: Type.Ref(Text.MarkdownString, {
140
+ description:
141
+ 'A markdown string containing the primary trigger text for this move.\n\nSecondary trigger text (for specific stats or uses of an asset ability) may be described in individual trigger conditions.',
142
+ type: 'string'
143
+ // pattern: /.*\.{3}/.source
144
+ })
145
+ })
146
+
147
+ export function Trigger<
148
+ T extends TFuzzyNull<TArray<TFuzzyRef<TTriggerCondition>>>
149
+ >(conditions: T, options: ObjectOptions = {}) {
150
+ return Assign(
151
+ TriggerMixin,
152
+ setDescriptions(Type.Object({ conditions }), {
153
+ conditions: 'Specific conditions that qualify for this trigger.'
154
+ }),
155
+ options
156
+ ) as TTrigger<T>
157
+ }
158
+ export type TTrigger<
159
+ T extends TFuzzyNull<TArray<TFuzzyRef<TTriggerCondition>>> = TFuzzyNull<
160
+ TArray<TFuzzyRef<TTriggerCondition>>
161
+ >
162
+ > = TObject<(typeof TriggerMixin)['properties'] & { conditions: T }>
163
+
164
+ export type Trigger<
165
+ T extends TriggerCondition[] | null = TriggerCondition[] | null
166
+ > = Static<typeof TriggerMixin> & { conditions: T }
167
+
168
+ export function TriggerEnhancement<
169
+ T extends TFuzzyNull<TArray<TFuzzyRef<TTriggerCondition>>>
170
+ >(conditions: T, options: ObjectOptions) {
171
+ return Type.Object(
172
+ {
173
+ conditions: {
174
+ description: 'Trigger conditions added to the enhanced move.',
175
+ ...conditions
176
+ } as T
177
+ },
178
+ {
179
+ description:
180
+ "Describes changes/additions made to the enhanced move's trigger conditions.",
181
+ ...options
182
+ }
183
+ )
184
+ }
185
+
186
+ export type TTriggerEnhancement<
187
+ T extends TFuzzyNull<TArray<TFuzzyRef<TTriggerCondition>>> = TFuzzyNull<
188
+ TArray<TFuzzyRef<TTriggerCondition>>
189
+ >
190
+ > = ReturnType<typeof TriggerEnhancement<T>>
191
+ export type TriggerEnhancement<
192
+ T extends TriggerCondition[] | null = TriggerCondition[] | null
193
+ > = { conditions: T }