@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,21 @@
1
+ /**
2
+ * TypeBox schema functions representing utility types. Used internally to compose schemata, but not part of the final Datasworn schema output.
3
+ */
4
+
5
+ export * from './utils/Computed.js'
6
+ export * from './utils/DiscriminatedUnion.js'
7
+ export * from './utils/ExtractLiteralFromEnum.js'
8
+ export * from './utils/NonNullable.js'
9
+ export * from './utils/Nullable.js'
10
+ export * from './utils/ObjectLiteral.js'
11
+ export * from './utils/OmitMeta.js'
12
+ export * from './utils/OmitOptional.js'
13
+ export * from './utils/PartialExcept.js'
14
+ // depends on Nullable
15
+ export * from './utils/SetNullable.js'
16
+ // depends on Assign
17
+ export * from './utils/SetOptional.js'
18
+ export * from './utils/UnionEnum.js'
19
+ // depends on UnionEnum
20
+ export * from './utils/UnionEnumFromRecord.js'
21
+ export * from './utils/UnionOneOf.js'
@@ -0,0 +1,79 @@
1
+ import { type Static, Type } from '@sinclair/typebox'
2
+ import Id from '../common/Id.js'
3
+ import * as Text from '../common/Text.js'
4
+ import * as Generic from '../Generic.js'
5
+ import { EmbeddedMove } from '../moves/EmbeddedMove.js'
6
+ import { MoveEnhancement } from '../moves/MoveEnhancement.js'
7
+ import { EmbeddedOracleRollable } from '../oracles/EmbeddedOracleRollable.js'
8
+ import { AssetEnhancement } from './Enhancement.js'
9
+ import { AssetAbilityControlField, AssetAbilityOptionField } from './Fields.js'
10
+
11
+ export const AssetAbility = Generic.IdNode(
12
+ Type.Object({
13
+ name: Type.Optional(
14
+ Type.Ref(Text.Label, {
15
+ description:
16
+ 'A handful of asset abilities have a label/name, for instance classic Ironsworn companion assets. Most canonical assets omit this property.'
17
+ })
18
+ ),
19
+ text: Type.Ref(Text.MarkdownString, {
20
+ description: 'The complete rules text of this asset ability.'
21
+ }),
22
+ enabled: Type.Boolean({
23
+ default: false,
24
+ description: 'Is this asset ability enabled?'
25
+ }),
26
+ moves: Type.Optional(
27
+ Generic.Dictionary(
28
+ Type.Ref(EmbeddedMove, { title: 'AssetAbilityMove' }),
29
+ {
30
+ title: 'AssetAbilityMoves',
31
+ description: 'Unique moves added by this asset ability.'
32
+ }
33
+ )
34
+ ),
35
+ oracles: Type.Optional(
36
+ Generic.Dictionary(
37
+ Type.Ref(EmbeddedOracleRollable, {
38
+ title: 'AssetAbilityOracleRollable'
39
+ }),
40
+ {
41
+ title: 'AssetAbilityOracles'
42
+ }
43
+ )
44
+ ),
45
+ options: Type.Optional(
46
+ Generic.Dictionary(Type.Ref(AssetAbilityOptionField), {
47
+ description:
48
+ 'Fields that are expected to be set once and remain the same through the life of the asset.'
49
+ })
50
+ ),
51
+ controls: Type.Optional(
52
+ Generic.Dictionary(Type.Ref(AssetAbilityControlField), {
53
+ description:
54
+ 'Fields whose values are expected to change over the life of the asset.'
55
+ })
56
+ ),
57
+ enhance_asset: Type.Optional(
58
+ Type.Ref(AssetEnhancement, {
59
+ description: 'Changes made to the asset, when this ability is enabled.'
60
+ })
61
+ ),
62
+ enhance_moves: Type.Optional(
63
+ Type.Array(Type.Ref(MoveEnhancement), {
64
+ description:
65
+ 'Describes changes made to various moves by this asset ability. Usually these require specific trigger conditions.'
66
+ // releaseStage: 'experimental'
67
+ })
68
+ ),
69
+ tags: Type.Optional(Type.Ref('Tags'))
70
+ }),
71
+ Type.Ref(Id.AssetAbilityId),
72
+ {
73
+ $id: 'AssetAbility',
74
+ description:
75
+ 'An asset ability: one of the purchasable features of an asset. Most assets have three.'
76
+ }
77
+ )
78
+ export type AssetAbility = Static<typeof AssetAbility>
79
+ export type TAssetAbility = typeof AssetAbility
@@ -0,0 +1,62 @@
1
+ import { type Static, Type } from '@sinclair/typebox'
2
+ import * as Fields from '../common/Fields.js'
3
+ import Id from '../common/Id.js'
4
+ import { DiscriminatedUnion } from '../utils/DiscriminatedUnion.js'
5
+ import { Nullable } from '../utils/Nullable.js'
6
+ import { NoDefaults } from '../utils/typebox.js'
7
+ import { AssetPropertiesEnhanceable } from './common.js'
8
+ import { AssetConditionMeter } from './Fields.js'
9
+
10
+ export const AssetAttachment = Type.Object(
11
+ {
12
+ assets: Type.Array(Type.Ref(Id.AssetIdWildcard), {
13
+ description:
14
+ 'Asset IDs (which may be wildcards) that may be attached to this asset'
15
+ }),
16
+ max: Nullable(Type.Integer({ minimum: 1 }), {
17
+ default: null,
18
+ description:
19
+ "Null if there's no upper limit to the number of attached assets."
20
+ })
21
+ },
22
+ {
23
+ $id: 'AssetAttachment',
24
+ description:
25
+ "Describes which assets can be attached to this asset. Example: Starforged's Module assets, which can be equipped by Command Vehicle assets. See p. 55 of Starforged for more info."
26
+ }
27
+ )
28
+ export type TAssetAttachment = typeof AssetAttachment
29
+ export type AssetAttachment = Static<TAssetAttachment>
30
+
31
+ export const AssetConditionMeterEnhancement = NoDefaults(
32
+ // for the moment, it's only practical to enhance condition meters
33
+
34
+ Type.Pick(AssetConditionMeter, ['field_type', 'max']),
35
+ {
36
+ $id: 'AssetConditionMeterEnhancement'
37
+ }
38
+ )
39
+ export type AssetConditionMeterEnhancement = Static<
40
+ typeof AssetConditionMeterEnhancement
41
+ >
42
+
43
+ export const AssetControlFieldEnhancement = DiscriminatedUnion(
44
+ {
45
+ condition_meter: AssetConditionMeterEnhancement
46
+ },
47
+ Fields.DISCRIMINATOR,
48
+ { $id: 'AssetControlFieldEnhancement' }
49
+ )
50
+
51
+ export const AssetEnhancement = NoDefaults(
52
+ Type.Partial(
53
+ AssetPropertiesEnhanceable(Type.Ref(AssetControlFieldEnhancement))
54
+ ),
55
+ {
56
+ description:
57
+ 'Describes enhancements made to this asset in a partial asset object. The changes should be applied recursively; only the values that are specified should be changed.',
58
+ $id: 'AssetEnhancement'
59
+ }
60
+ )
61
+ export type TAssetEnhancement = typeof AssetEnhancement
62
+ export type AssetEnhancement = Static<typeof AssetEnhancement>
@@ -0,0 +1,285 @@
1
+ import { type Static, Type } from '@sinclair/typebox'
2
+ import type { Simplify } from 'type-fest'
3
+ import * as Fields from '../common/Fields.js'
4
+ import * as Generic from '../Generic.js'
5
+ import { DiscriminatedUnion } from '../Utils.js'
6
+ import { Assign } from '../utils/FlatIntersect.js'
7
+
8
+ const AssetBooleanFieldMixin = Type.Object({
9
+ is_impact: Type.Boolean({
10
+ default: false,
11
+ description:
12
+ 'Does this field count as an impact (Starforged) or debility (Ironsworn classic) when its value is set to `true`?'
13
+ }),
14
+ disables_asset: Type.Boolean({
15
+ default: false,
16
+ description:
17
+ 'Does this field disable the asset when its value is set to `true`?'
18
+ })
19
+ })
20
+
21
+ // function AssetCheckboxField(
22
+ // // _id:Id.TAnyId,
23
+ // options: ObjectOptions = {}
24
+ // ) {
25
+ // const base = Fields.CheckboxField
26
+ // // id
27
+ // // ()
28
+ // const { $comment, description } = base
29
+ // return Assign(
30
+ // [
31
+ // Fields.CheckboxField,
32
+ // // id
33
+ // // (),
34
+ // AssetBooleanFieldMixin
35
+ // ],
36
+ // {
37
+ // description,
38
+ // $comment,
39
+ // ...options
40
+ // }
41
+ // )
42
+ // }
43
+ // function AssetCardFlipField(
44
+ // // _id:Id.TAnyId,
45
+ // options: ObjectOptions = {}
46
+ // ) {
47
+ // const base = Fields
48
+ // .CardFlipField
49
+ // // id
50
+ // ()
51
+ // const { $comment, description } = base
52
+ // return Assign([base, AssetBooleanFieldMixin], {
53
+ // description,
54
+ // $comment,
55
+ // title: 'AssetCardFlipField',
56
+ // ...options
57
+ // })
58
+ // }
59
+ export const AssetCheckboxField = Assign(
60
+ Fields.CheckboxField,
61
+ AssetBooleanFieldMixin,
62
+ { $id: 'AssetCheckboxField' }
63
+ )
64
+ export const AssetCardFlipField = Assign(
65
+ Fields.CardFlipField,
66
+ AssetBooleanFieldMixin,
67
+ { $id: 'AssetCardFlipField' }
68
+ )
69
+
70
+ export const AssetConditionMeterControlField = DiscriminatedUnion(
71
+ { checkbox: AssetCheckboxField, card_flip: AssetCardFlipField },
72
+ // .map(
73
+ // (fn) => fn()
74
+ // Type.Ref(Id.AssetConditionMeterControlFieldId
75
+ // )
76
+ // )
77
+ Fields.DISCRIMINATOR,
78
+ {
79
+ $id: 'AssetConditionMeterControlField',
80
+ description:
81
+ 'A checkbox control field, rendered as part of an asset condition meter.'
82
+ }
83
+ )
84
+ export type AssetConditionMeterControlField = Static<
85
+ typeof AssetConditionMeterControlField
86
+ >
87
+ const AssetConditionMeterMixin = Type.Object({
88
+ moves: Type.Optional(
89
+ Type.Object(
90
+ {
91
+ suffer: Type.Optional(
92
+ Type.Array(
93
+ Type.Ref('AnyMoveIdWildcard', {
94
+ examples: [
95
+ 'move:classic/suffer/companion_endure_harm',
96
+ 'move:starforged/suffer/companion_takes_a_hit',
97
+ 'move:starforged/suffer/withstand_damage'
98
+ ]
99
+ }),
100
+ {
101
+ description:
102
+ 'The ID(s) of suffer moves associated with the condition meter. If the suffer move makes an action roll, this condition meter value should be made available as a roll option.'
103
+ }
104
+ )
105
+ ),
106
+ recover: Type.Optional(
107
+ Type.Array(
108
+ Type.Ref('AnyMoveIdWildcard', {
109
+ examples: [
110
+ 'move:classic/adventure/heal',
111
+ 'move:classic/adventure/make_camp',
112
+ 'move:classic/relationship/sojourn',
113
+ 'move:starforged/recover/heal',
114
+ 'move:starforged/recover/repair'
115
+ ]
116
+ }),
117
+ {
118
+ description:
119
+ 'The ID(s) of recovery moves associated with this meter.'
120
+ }
121
+ )
122
+ )
123
+ },
124
+ {
125
+ description:
126
+ 'Provides hints for moves that interact with this condition meter, such as suffer and recovery moves.',
127
+ releaseStage: 'experimental'
128
+ }
129
+ )
130
+ ),
131
+ controls: Generic.Dictionary(Type.Ref(AssetConditionMeterControlField), {
132
+ description: 'Checkbox controls rendered as part of the condition meter.'
133
+ })
134
+ })
135
+
136
+ export const AssetConditionMeter = Assign(
137
+ Fields.ConditionMeterField,
138
+ // Type.Ref(Id.AssetControlFieldId)
139
+ // ()
140
+ AssetConditionMeterMixin,
141
+ {
142
+ $id: 'AssetConditionMeter',
143
+ description:
144
+ 'Some assets provide a special condition meter of their own. The most common example is the health meters on companion assets. Asset condition meters may also include their own controls, such as the checkboxes that Starforged companion assets use to indicate they are "out of action".'
145
+ }
146
+ )
147
+
148
+ export type AssetConditionMeter = Simplify<Static<typeof AssetConditionMeter>>
149
+
150
+ // const AssetOptionFields = [
151
+ // Fields.SelectValueField,
152
+ // Fields.SelectEnhancementField,
153
+ // Fields.TextField
154
+ // ].map((fn) => fn(Type.Ref(Id.AssetOptionFieldId)))
155
+
156
+ // export const AssetSelectValueOptionField = Fields.SelectValueField(
157
+ // // Type.Ref(Id.AssetOptionFieldId),
158
+ // { $id: 'AssetSelectValueOptionField' }
159
+ // )
160
+ // export const AssetSelectEnhancementOptionField = Fields.SelectEnhancementField(
161
+ // // Type.Ref(Id.AssetOptionFieldId),
162
+ // { $id: 'AssetSelectEnhancementOptionField' }
163
+ // )
164
+ // export const AssetTextOptionField = Fields.TextField(
165
+ // // Type.Ref(Id.AssetOptionFieldId),
166
+ // {
167
+ // $id: 'AssetTextOptionField'
168
+ // }
169
+ // )
170
+
171
+ export const AssetOptionField = DiscriminatedUnion(
172
+ {
173
+ select_value: Fields.SelectValueField,
174
+ select_enhancement: Fields.SelectEnhancementField,
175
+ text: Fields.TextField
176
+ },
177
+ Fields.DISCRIMINATOR,
178
+ {
179
+ $id: 'AssetOptionField',
180
+ description:
181
+ 'Options are asset input fields which are set once, usually when the character takes the asset. The most common example is the "name" field on companion assets. A more complex example is the choice of a god\'s stat for the Devotant asset.'
182
+ }
183
+ )
184
+ export type AssetOptionField = Static<typeof AssetOptionField>
185
+ export type TAssetOptionField = typeof AssetOptionField
186
+
187
+ // const AssetControlFields = [
188
+ // AssetConditionMeter,
189
+ // ...[
190
+ // Fields.SelectEnhancementField,
191
+ // AssetCheckboxField,
192
+ // AssetCardFlipField
193
+ // ].map((fn) => fn(Type.Ref(Id.AssetControlFieldId)))
194
+ // ]
195
+
196
+ // export const AssetSelectEnhancementControlField = Fields.SelectEnhancementField(
197
+ // // Type.Ref(Id.AssetControlFieldId),
198
+ // { $id: 'AssetSelectEnhancementControlField' }
199
+ // )
200
+ // export const AssetCheckboxControlField = AssetCheckboxField(
201
+ // // Type.Ref(Id.AssetControlFieldId),
202
+ // { $id: 'AssetCheckboxControlField' }
203
+ // )
204
+ // export const AssetCardFlipControlField = AssetCardFlipField(
205
+ // // Type.Ref(Id.AssetControlFieldId),
206
+ // { $id: 'AssetCardFlipControlField' }
207
+ // )
208
+
209
+ export const AssetControlField = DiscriminatedUnion(
210
+ {
211
+ condition_meter: AssetConditionMeter,
212
+ select_enhancement: Fields.SelectEnhancementField,
213
+ checkbox: AssetCheckboxField,
214
+ card_flip: AssetCardFlipField
215
+ },
216
+ Fields.DISCRIMINATOR,
217
+ {
218
+ $id: 'AssetControlField'
219
+ }
220
+ )
221
+
222
+ export type TAssetControlField = typeof AssetControlField
223
+ export type AssetControlField = Static<typeof AssetControlField>
224
+
225
+ // const AbilityControlFields = [
226
+ // Fields.ClockField,
227
+ // Fields.CounterField,
228
+ // AssetCheckboxField
229
+ // ].map((fn) => fn(Type.Ref(Id.AssetAbilityControlFieldId)))
230
+
231
+ // export const AssetAbilityClock = Fields.ClockField(
232
+ // // Type.Ref(Id.AssetAbilityControlFieldId),
233
+ // { $id: 'AssetAbilityClock' }
234
+ // )
235
+
236
+ // export const AssetAbilityCounter = Fields.CounterField(
237
+ // // Type.Ref(Id.AssetAbilityControlFieldId),
238
+ // { $id: 'AssetAbilityCounter' }
239
+ // )
240
+
241
+ // export const AssetAbilityCheckbox = AssetCheckboxField(
242
+ // // Type.Ref(Id.AssetAbilityControlFieldId),
243
+ // { $id: 'AssetAbilityCheckbox' }
244
+ // )
245
+
246
+ export const AssetAbilityControlField = DiscriminatedUnion(
247
+ {
248
+ clock: Fields.ClockField,
249
+ counter: Fields.CounterField,
250
+ checkbox: AssetCheckboxField,
251
+ text: Fields.TextField
252
+ },
253
+ Fields.DISCRIMINATOR,
254
+ { $id: 'AssetAbilityControlField' }
255
+ )
256
+
257
+ export type AssetAbilityControlField = Static<typeof AssetAbilityControlField>
258
+
259
+ // const AbilityOptionFields = [Fields.TextField]
260
+ // .map
261
+ // // (fn) => fn()
262
+ // // Type.Ref(Id.AssetAbilityOptionFieldId)
263
+ // ()
264
+
265
+ export const AssetAbilityOptionField = DiscriminatedUnion(
266
+ {
267
+ text: Fields.TextField
268
+ },
269
+ Fields.DISCRIMINATOR,
270
+ { $id: 'AssetAbilityOptionField' }
271
+ )
272
+
273
+ export type AssetAbilityOptionField = Static<typeof AssetAbilityOptionField>
274
+
275
+ export {
276
+ ClockField,
277
+ ConditionMeterField,
278
+ CounterField,
279
+ SelectEnhancementField,
280
+ SelectEnhancementFieldChoice,
281
+ SelectEnhancementFieldChoiceGroup,
282
+ SelectValueField,
283
+ SelectValueFieldChoice,
284
+ TextField
285
+ } from '../common/Fields.js'
@@ -0,0 +1,29 @@
1
+ import { type TSchema, Type } from '@sinclair/typebox'
2
+ import * as Metadata from '../common/Metadata.js'
3
+
4
+ import * as Generic from '../generic/Dictionary.js'
5
+
6
+ export function AssetPropertiesEnhanceable<Control extends TSchema>(
7
+ controlSchema: Control
8
+ ) {
9
+ return Type.Object({
10
+ controls: Type.Optional(
11
+ Generic.Dictionary(controlSchema, {
12
+ description:
13
+ 'Controls are condition meters, clocks, counters, and other asset input fields whose values are expected to change throughout the life of the asset.'
14
+ })
15
+ ),
16
+ suggestions: Type.Optional(Type.Ref(Metadata.Suggestions)),
17
+ count_as_impact: Type.Boolean({
18
+ default: false,
19
+ description:
20
+ 'If `true`, this asset counts as an impact (Starforged) or a debility (classic Ironsworn).'
21
+ }),
22
+ attachments: Type.Optional(Type.Ref('AssetAttachment')),
23
+ shared: Type.Boolean({
24
+ default: false,
25
+ description:
26
+ "Most assets only benefit to their owner, but certain assets (like Starforged's module and command vehicle assets) are shared amongst the player's allies, too."
27
+ })
28
+ })
29
+ }