@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,136 @@
1
+ import {
2
+ type Static,
3
+ type TAnySchema,
4
+ type TBigInt,
5
+ Type
6
+ } from '@sinclair/typebox'
7
+ import * as Text from '../common/Text.js'
8
+ import * as Utils from '../Utils.js'
9
+ import { UnionEnumFromRecord } from '../utils/UnionEnumFromRecord.js'
10
+
11
+ enum Outcome {
12
+ Miss = 'miss',
13
+ WeakHit = 'weak_hit',
14
+ StrongHit = 'strong_hit'
15
+ }
16
+
17
+ enum RollMethod {
18
+ Miss = 'miss',
19
+ WeakHit = 'weak_hit',
20
+ StrongHit = 'strong_hit',
21
+ PlayerChoice = 'player_choice',
22
+ Highest = 'highest',
23
+ Lowest = 'lowest',
24
+ All = 'all'
25
+ }
26
+
27
+ // ENUMS
28
+
29
+ export const MoveRollType = UnionEnumFromRecord(
30
+ {
31
+ no_roll: 'A move that makes no action rolls or progress rolls.',
32
+ action_roll: 'A move that makes an action roll.',
33
+ progress_roll:
34
+ 'A progress move that rolls on a standard progress track type (defined by this move).',
35
+ special_track:
36
+ 'A progress move that rolls on one or more special tracks, like Bonds (classic Ironsworn), Failure (Delve), or Legacies (Starforged).'
37
+ },
38
+ { $id: 'MoveRollType' }
39
+ )
40
+
41
+ export type MoveRollType = Static<typeof MoveRollType>
42
+ export type TMoveRollType = typeof MoveRollType
43
+
44
+ const MoveOutcomeType = UnionEnumFromRecord(
45
+ {
46
+ [Outcome.Miss]: "The score doesn't beat either challenge die.",
47
+ [Outcome.WeakHit]: 'The score is greater than one challenge die.',
48
+ [Outcome.StrongHit]: 'The score is greater than both challenge dice.'
49
+ },
50
+ {
51
+ $id: 'MoveOutcomeType'
52
+ }
53
+ )
54
+ type _MoveOutcomeType = Static<typeof MoveOutcomeType>
55
+
56
+ const rollMethodForceOutcome = {
57
+ [RollMethod.Miss]: 'An automatic miss.',
58
+ [RollMethod.WeakHit]: 'An automatic weak hit.',
59
+ [RollMethod.StrongHit]: 'An automatic strong hit.'
60
+ }
61
+
62
+ const rollMethodOutcomeCommon = {
63
+ [RollMethod.PlayerChoice]: 'The player chooses which roll option to use.',
64
+ [RollMethod.Highest]: 'Use the roll option with the best/highest value.',
65
+ [RollMethod.Lowest]: 'Use the roll option with the worst/lowest value.',
66
+ [RollMethod.All]: 'Use _every_ roll option at once.'
67
+ }
68
+
69
+ export const ActionRollMethod = UnionEnumFromRecord(
70
+ {
71
+ ...rollMethodForceOutcome,
72
+ ...rollMethodOutcomeCommon
73
+ },
74
+ { $id: 'ActionRollMethod' }
75
+ )
76
+ export type ActionRollMethod = Static<typeof ActionRollMethod>
77
+
78
+ export const SpecialTrackRollMethod = UnionEnumFromRecord(
79
+ {
80
+ ...rollMethodForceOutcome,
81
+ ...rollMethodOutcomeCommon
82
+ },
83
+ { $id: 'SpecialTrackRollMethod' }
84
+ )
85
+
86
+ export type SpecialTrackRollMethod = Static<typeof SpecialTrackRollMethod>
87
+
88
+ export const ProgressRollMethod = UnionEnumFromRecord(
89
+ {
90
+ ...rollMethodForceOutcome,
91
+ progress_roll:
92
+ 'Make a progress roll on a progress track associated with this move.'
93
+ },
94
+ { $id: 'ProgressRollMethod' }
95
+ )
96
+ export type ProgressRollMethod = Static<typeof ProgressRollMethod>
97
+
98
+ export const MoveOutcome = Type.Object(
99
+ {
100
+ _id: Utils.Computed(Type.Ref('AnyMoveOutcomeId')),
101
+ text: Type.Ref(Text.MarkdownString, {
102
+ // pattern: /On a __(strong hit|weak hit|miss)__/.source,
103
+ // type: 'string'
104
+ }),
105
+ oracle_rolls: Type.Optional(Type.Array(Type.Ref('OracleRoll')))
106
+ // count_as: Type.Optional(Type.Ref(MoveOutcomeType))
107
+ },
108
+ { $id: 'MoveOutcome' }
109
+ )
110
+ export type MoveOutcome = Static<typeof MoveOutcome>
111
+
112
+ // export const MoveOutcomeMatchable = Assign(
113
+ // [ MoveOutcome, Type.Object({ match: Type.Optional(Type.Ref(MoveOutcome)) })],
114
+ // { $id: 'MoveOutcomeMatchable' }
115
+ // )
116
+ // export type MoveOutcomeMatchable = Static<typeof MoveOutcomeMatchable>
117
+
118
+ export const MoveOutcomes = Type.Object(
119
+ {
120
+ [Outcome.StrongHit]: Type.Ref('MoveOutcome'),
121
+ // [Outcome.StrongHit]: Type.Ref<typeof MoveOutcomeMatchable>('MoveOutcomeMatchable'),
122
+ [Outcome.WeakHit]: Type.Ref('MoveOutcome'),
123
+ [Outcome.Miss]: Type.Ref('MoveOutcome')
124
+ // [Outcome.Miss]: Type.Ref<typeof MoveOutcomeMatchable>('MoveOutcomeMatchable'),
125
+ },
126
+ {
127
+ $id: 'MoveOutcomes',
128
+ description: `A standalone localized description for each move outcome (miss, weak hit, or strong hit). This is for for e.g. VTT implementations, where it's often useful to display only the rules text relevant to a roll result.
129
+
130
+ This often requires light editorialization to create text that can stand alone without reference to the rest of the move. For example, 'as above' (in reference to another move outcome) shouldn't be used here; instead, the relevant text should be repeated.`
131
+ }
132
+ )
133
+ export type MoveOutcomes = Static<typeof MoveOutcomes>
134
+ export type TMoveOutcomes = typeof MoveOutcomes
135
+
136
+ export type SchemaOf<T> = Exclude<TAnySchema, TBigInt> & { static: T }
@@ -0,0 +1,13 @@
1
+ // parts
2
+
3
+ // subtypes
4
+ export * from './ActionRoll.js'
5
+ export * from './common.js'
6
+ export * from './EmbeddedMove.js'
7
+ // primary type
8
+ export * from './Move.js'
9
+ // derived types
10
+ export * from './MoveCategory.js'
11
+ export * from './MoveEnhancement.js'
12
+ export * from './ProgressRoll.js'
13
+ export { TriggerBy } from './Trigger.js'
@@ -0,0 +1,132 @@
1
+ import {
2
+ type ObjectOptions,
3
+ type Static,
4
+ type TBoolean,
5
+ type TLiteral,
6
+ type TNull,
7
+ type TRef,
8
+ type TRefUnsafe,
9
+ Type
10
+ } from '@sinclair/typebox'
11
+ import type { SetRequired } from 'type-fest'
12
+ import Id from '../common/Id.js'
13
+ import * as Text from '../common/Text.js'
14
+ import * as Generic from '../Generic.js'
15
+ import { EmbeddedOracleRollable } from '../oracles/EmbeddedOracleRollable.js'
16
+ import { ExtractLiteralFromEnum } from '../utils/ExtractLiteralFromEnum.js'
17
+ import { FlatIntersect } from '../utils/FlatIntersect.js'
18
+ import {
19
+ type MoveOutcomes,
20
+ MoveRollType,
21
+ type TMoveOutcomes
22
+ } from './common.js'
23
+ import type { Trigger, TTrigger, TTriggerEnhancement } from './Trigger.js'
24
+
25
+ /** The property key used to discriminate move subtypes */
26
+ export const moveDiscriminator = 'roll_type'
27
+
28
+ const MoveBase = Type.Object({
29
+ replaces: Type.Optional(
30
+ Type.Array(Type.Ref(Id.MoveIdWildcard), {
31
+ description:
32
+ 'Indicates that this move replaces the identified moves. References to the replaced moves can be considered equivalent to this move.'
33
+ })
34
+ ),
35
+ text: Type.Ref(Text.MarkdownString, {
36
+ description: 'The complete rules text of the move.'
37
+ }),
38
+ oracles: Type.Optional(
39
+ Generic.Dictionary(
40
+ Type.Ref(EmbeddedOracleRollable, { title: 'MoveOracleRollable' }),
41
+ { title: 'MoveOracles' }
42
+ )
43
+ )
44
+ })
45
+
46
+ export function Move<
47
+ RollType extends MoveRollType,
48
+ Trigger extends TRefUnsafe<TTrigger> | TRef<string>,
49
+ Outcomes extends TRefUnsafe<TMoveOutcomes> | TRef<string> | TNull
50
+ >(
51
+ rollType: RollType,
52
+ trigger: Trigger,
53
+ outcomes: Outcomes,
54
+ options: SetRequired<ObjectOptions, '$id'>
55
+ ) {
56
+ let allow_momentum_burn: TLiteral<boolean> | TBoolean
57
+
58
+ const description = 'Is burning momentum allowed for this move?'
59
+
60
+ switch (rollType) {
61
+ case 'action_roll':
62
+ allow_momentum_burn = Type.Boolean({
63
+ default: true,
64
+ description
65
+ })
66
+ break
67
+ default:
68
+ allow_momentum_burn = Type.Literal(false, { default: false, description })
69
+ break
70
+ }
71
+
72
+ const base = FlatIntersect([
73
+ MoveBase,
74
+ Type.Object({
75
+ trigger: {
76
+ title: 'Trigger',
77
+ description: 'Trigger conditions for this move.',
78
+ ...trigger
79
+ } as Trigger,
80
+ allow_momentum_burn,
81
+ outcomes: { title: 'MoveOutcomes', ...outcomes } as Outcomes
82
+ })
83
+ ])
84
+
85
+ return Generic.CollectableSubtypeNode(
86
+ base,
87
+ 'move',
88
+ moveDiscriminator,
89
+ rollType,
90
+ options
91
+ )
92
+ }
93
+ export type TMove<
94
+ RollType extends MoveRollType,
95
+ MoveTrigger extends TRefUnsafe<TTrigger>,
96
+ Outcomes extends TRefUnsafe<TMoveOutcomes> | TNull
97
+ > = ReturnType<typeof Move<RollType, MoveTrigger, Outcomes>>
98
+
99
+ export type Move<
100
+ RollType extends MoveRollType,
101
+ MoveTrigger extends Trigger,
102
+ Outcomes extends MoveOutcomes | null
103
+ > = Generic.Collectable<
104
+ Static<typeof MoveBase> & {
105
+ [moveDiscriminator]: RollType
106
+ trigger: MoveTrigger
107
+ outcomes: Outcomes
108
+ allow_momentum_burn: TLiteral<boolean> | TBoolean
109
+ }
110
+ >
111
+
112
+ export function MoveEnhancement<
113
+ RollType extends MoveRollType,
114
+ Trigger extends TRefUnsafe<TTriggerEnhancement>
115
+ >(rollType: RollType, trigger: Trigger, options: ObjectOptions = {}) {
116
+ const base = Type.Object({
117
+ [moveDiscriminator]: ExtractLiteralFromEnum(MoveRollType, rollType, {
118
+ description: `A move must have this \`${moveDiscriminator}\` to receive this enhancement. This is in addition to any other restrictions made by other properties.`
119
+ }),
120
+ trigger: Type.Optional(trigger)
121
+ })
122
+
123
+ return Generic.EnhanceMany(base, Type.Ref('AnyMoveIdWildcard'), {
124
+ description:
125
+ 'An object that describes changes to a move. These changes should be applied recursively, altering only the specified properties; enhanced arrays should be concatencated with the original array value.',
126
+ ...options
127
+ })
128
+ }
129
+ export type MoveEnhancement<T extends MoveRollType, E> = Generic.EnhanceMany<{
130
+ [moveDiscriminator]: T
131
+ trigger?: E
132
+ }>
@@ -0,0 +1,23 @@
1
+ import * as Utils from '../Utils.js'
2
+
3
+ export const ObjectType = Utils.UnionEnumFromRecord({
4
+ // RulesPackages
5
+ ruleset: '',
6
+ rules_expansion: '',
7
+ // Collections
8
+ oracle_collection: '',
9
+ asset_collection: '',
10
+ move_category: '',
11
+ npc_collection: '',
12
+ atlas: '',
13
+
14
+ // collectables
15
+ oracle_rollable: '',
16
+ // ...subtypes
17
+ move: ''
18
+ // ...subtypes
19
+
20
+ // delve_site_theme
21
+ // delve_site_domain
22
+ // rarity
23
+ })
@@ -0,0 +1,28 @@
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 { OracleRollable } from './OracleRollable.js'
8
+
9
+ const oracleRollableMapping = mapValues(OracleRollable[Mapping], (schema, k) =>
10
+ EmbeddedPrimaryNode(schema, [], { $id: `EmbeddedOracle${pascalCase(k)}` })
11
+ )
12
+
13
+ export const {
14
+ column_text: EmbeddedOracleColumnText,
15
+ column_text2: EmbeddedOracleColumnText2,
16
+ column_text3: EmbeddedOracleColumnText3,
17
+ table_text: EmbeddedOracleTableText,
18
+ table_text2: EmbeddedOracleTableText2,
19
+ table_text3: EmbeddedOracleTableText3
20
+ } = oracleRollableMapping
21
+
22
+ export const EmbeddedOracleRollable = DiscriminatedUnion(
23
+ oracleRollableMapping,
24
+ 'oracle_type',
25
+ { $id: 'EmbeddedOracleRollable' }
26
+ )
27
+
28
+ export type EmbeddedOracleRollable = Static<typeof EmbeddedOracleRollable>
@@ -0,0 +1,140 @@
1
+ import { type Static, Type } from '@sinclair/typebox'
2
+ import * as Generic from '../Generic.js'
3
+ import * as Utils from '../Utils.js'
4
+ import {
5
+ OracleColumnText,
6
+ OracleColumnText2,
7
+ OracleColumnText3
8
+ } from './OracleRollable.js'
9
+ import {
10
+ SharedRollsLabels,
11
+ SharedText2Labels,
12
+ SharedText3Labels,
13
+ SharedTextLabels
14
+ } from './Table.js'
15
+
16
+ const OracleCollectionType = Utils.UnionEnumFromRecord(
17
+ {
18
+ tables: 'A grouping of separate tables.',
19
+ table_shared_rolls:
20
+ 'A table with one shared roll column, and multiple unique text columns.',
21
+ table_shared_text:
22
+ 'A table with multiple unique roll columns, and one shared text column.',
23
+ table_shared_text2:
24
+ 'A table with multiple unique roll columns, and 2 shared text columns.',
25
+ table_shared_text3:
26
+ 'A table with multiple unique roll columns, and 3 shared text columns.'
27
+ },
28
+ {
29
+ $id: 'OracleCollectionType'
30
+ }
31
+ )
32
+ type OracleCollectionType = Static<typeof OracleCollectionType>
33
+
34
+ const subtypeKey = 'oracle_type' as const
35
+
36
+ export const OracleTablesCollection = Generic.CollectionSubtypeNode(
37
+ Type.Object({}),
38
+ 'oracle_collection',
39
+ subtypeKey,
40
+ 'tables' satisfies OracleCollectionType,
41
+ Generic.Dictionary(Type.Ref('OracleRollableTable')),
42
+ Generic.Dictionary(Type.Ref('OracleCollection')),
43
+ {
44
+ $id: 'OracleTablesCollection',
45
+ description:
46
+ 'An OracleCollection that represents a category or grouping of tables, which may themselves be `OracleTablesCollection`s.'
47
+ }
48
+ )
49
+
50
+ export type TOracleTablesCollection = typeof OracleTablesCollection
51
+ export type OracleTablesCollection = Static<TOracleTablesCollection>
52
+
53
+ export const OracleTableSharedRolls = Generic.CollectionSubtypeNode(
54
+ Type.Object({
55
+ column_labels: SharedRollsLabels
56
+ }),
57
+ 'oracle_collection',
58
+ subtypeKey,
59
+ 'table_shared_rolls' satisfies OracleCollectionType,
60
+ Generic.Dictionary(Type.Ref(OracleColumnText)),
61
+ undefined,
62
+ {
63
+ $id: 'OracleTableSharedRolls',
64
+ description:
65
+ 'An OracleCollection representing a single table with one roll column and multiple text columns.'
66
+ }
67
+ )
68
+
69
+ export type TOracleTableSharedRolls = typeof OracleTableSharedRolls
70
+ export type OracleTableSharedRolls = Static<TOracleTableSharedRolls>
71
+
72
+ export const OracleTableSharedText = Generic.CollectionSubtypeNode(
73
+ Type.Object({
74
+ column_labels: SharedTextLabels
75
+ }),
76
+ 'oracle_collection',
77
+ subtypeKey,
78
+ 'table_shared_text' satisfies OracleCollectionType,
79
+ Generic.Dictionary(Type.Ref(OracleColumnText)),
80
+ undefined,
81
+ {
82
+ $id: 'OracleTableSharedText',
83
+ description:
84
+ 'An OracleCollection representing a single table with multiple roll columns and one text column.'
85
+ }
86
+ )
87
+
88
+ export type TOracleTableSharedText = typeof OracleTableSharedText
89
+ export type OracleTableSharedText = Static<TOracleTableSharedText>
90
+
91
+ export const OracleTableSharedText2 = Generic.CollectionSubtypeNode(
92
+ Type.Object({
93
+ column_labels: SharedText2Labels
94
+ }),
95
+ 'oracle_collection',
96
+ subtypeKey,
97
+ 'table_shared_text2' satisfies OracleCollectionType,
98
+ Generic.Dictionary(Type.Ref(OracleColumnText2)),
99
+ undefined,
100
+ {
101
+ $id: 'OracleTableSharedText2',
102
+ description:
103
+ 'An OracleCollection representing a single table with multiple roll columns, and 2 shared text columns.'
104
+ }
105
+ )
106
+ export type TOracleTableSharedText2 = typeof OracleTableSharedText2
107
+ export type OracleTableSharedText2 = Static<TOracleTableSharedText2>
108
+
109
+ export const OracleTableSharedText3 = Generic.CollectionSubtypeNode(
110
+ Type.Object({
111
+ column_labels: SharedText3Labels
112
+ }),
113
+ 'oracle_collection',
114
+ subtypeKey,
115
+ 'table_shared_text3' satisfies OracleCollectionType,
116
+ Generic.Dictionary(Type.Ref(OracleColumnText3)),
117
+ undefined,
118
+ {
119
+ $id: 'OracleTableSharedText3',
120
+ description:
121
+ 'An OracleCollection representing a single table with multiple roll columns, and 3 shared text columns.'
122
+ }
123
+ )
124
+ export type TOracleTableSharedText3 = typeof OracleTableSharedText3
125
+ export type OracleTableSharedText3 = Static<TOracleTableSharedText3>
126
+
127
+ export const OracleCollection = Utils.DiscriminatedUnion(
128
+ {
129
+ tables: OracleTablesCollection,
130
+ table_shared_rolls: OracleTableSharedRolls,
131
+ table_shared_text: OracleTableSharedText,
132
+ table_shared_text2: OracleTableSharedText2,
133
+ table_shared_text3: OracleTableSharedText3
134
+ },
135
+ subtypeKey,
136
+ { $id: 'OracleCollection' }
137
+ )
138
+
139
+ export type TOracleCollection = typeof OracleCollection
140
+ export type OracleCollection = Static<TOracleCollection>
@@ -0,0 +1,207 @@
1
+ import {
2
+ type ObjectOptions,
3
+ type Static,
4
+ type TObject,
5
+ type TRefUnsafe,
6
+ type TSchema,
7
+ Type
8
+ } from '@sinclair/typebox'
9
+ import type { SetRequired } from 'type-fest'
10
+ import * as Rolls from '../common/Rolls.js'
11
+ import { CollectableSubtypeNode } from '../generic/CollectableNode.js'
12
+ import * as Utils from '../Utils.js'
13
+ import { FlatIntersect } from '../utils/FlatIntersect.js'
14
+ import {
15
+ Text2ColumnLabels,
16
+ Text3ColumnLabels,
17
+ TextColumnLabels
18
+ } from './Table.js'
19
+ import {
20
+ OracleRollableRowText,
21
+ OracleRollableRowText2,
22
+ OracleRollableRowText3
23
+ } from './TableRow.js'
24
+
25
+ // metadata necessary to generate a roll result from an OracleRollable
26
+ const RollableMeta = Type.Object({
27
+ recommended_rolls: Type.Optional(
28
+ Type.Object({
29
+ min: Type.Integer({ default: 1 }),
30
+ max: Type.Integer({ default: 1 })
31
+ })
32
+ ),
33
+ dice: Type.Ref(Rolls.DiceExpression, {
34
+ default: '1d100',
35
+ description: 'The roll used to select a result on this oracle.'
36
+ }),
37
+ match: Type.Optional(
38
+ Type.Ref(Rolls.OracleMatchBehavior, {
39
+ description:
40
+ 'Most oracle tables are insensitive to matches, but a few define special match behavior.'
41
+ })
42
+ )
43
+ })
44
+
45
+ const subtypeKey = 'oracle_type' as const
46
+
47
+ function OracleRollableBase<TBase extends TObject, _TSubtype extends string>(
48
+ base: TBase,
49
+ row: TRefUnsafe<TObject>,
50
+ options: ObjectOptions = {}
51
+ ) {
52
+ const enhancedBase = FlatIntersect(
53
+ [
54
+ RollableMeta,
55
+ Type.Object({
56
+ rows: Type.Array(row, {
57
+ description:
58
+ 'An array of objects, each representing a single row of the table.',
59
+ rollable: true
60
+ })
61
+ }),
62
+ base
63
+ ],
64
+ options
65
+ )
66
+
67
+ return enhancedBase
68
+ }
69
+ function RollableTable<TRow extends TObject, TSubtype extends string>(
70
+ subtype: TSubtype,
71
+ row: TRefUnsafe<TRow>,
72
+ column_labels: TSchema,
73
+ options: SetRequired<ObjectOptions, '$id'>
74
+ ) {
75
+ return CollectableSubtypeNode(
76
+ OracleRollableBase(Type.Object({ column_labels }), row),
77
+ 'oracle_rollable',
78
+ subtypeKey,
79
+ subtype,
80
+ options
81
+ )
82
+ }
83
+
84
+ function RollableColumn<TRow extends TObject, TSubtype extends string>(
85
+ subtype: TSubtype,
86
+ row: TRefUnsafe<TRow>,
87
+ options: SetRequired<ObjectOptions, '$id'>
88
+ ) {
89
+ return Type.Omit(
90
+ CollectableSubtypeNode(
91
+ OracleRollableBase(Type.Object({}), row),
92
+ 'oracle_rollable',
93
+ subtypeKey,
94
+ subtype,
95
+ options
96
+ ),
97
+ ['_source'],
98
+ options
99
+ )
100
+ }
101
+
102
+ export const OracleTableText = RollableTable(
103
+ 'table_text',
104
+ Type.Ref(OracleRollableRowText),
105
+ TextColumnLabels,
106
+ {
107
+ $id: 'OracleTableText',
108
+ description:
109
+ 'Represents a basic rollable oracle table with one roll column and one text result column.'
110
+ }
111
+ )
112
+ export type TOracleTableText = typeof OracleTableText
113
+ export type OracleTableText = Static<typeof OracleTableText>
114
+
115
+ export const OracleTableText2 = RollableTable(
116
+ 'table_text2',
117
+ Type.Ref(OracleRollableRowText2),
118
+ Text2ColumnLabels,
119
+ {
120
+ $id: 'OracleTableText2',
121
+ description:
122
+ 'A rollable oracle table with one roll column and two text columns.'
123
+ }
124
+ )
125
+ export type TOracleTableText2 = typeof OracleTableText2
126
+ export type OracleTableText2 = Static<typeof OracleTableText2>
127
+
128
+ export const OracleTableText3 = RollableTable(
129
+ 'table_text3',
130
+ Type.Ref(OracleRollableRowText3),
131
+ Text3ColumnLabels,
132
+ {
133
+ $id: 'OracleTableText3',
134
+ description:
135
+ 'A rollable oracle table with one roll column and 3 text columns.'
136
+ }
137
+ )
138
+ export type TOracleTableText3 = typeof OracleTableText3
139
+ export type OracleTableText3 = Static<typeof OracleTableText2>
140
+
141
+ export const OracleColumnText = RollableColumn(
142
+ 'column_text',
143
+ Type.Ref(OracleRollableRowText),
144
+ {
145
+ $id: 'OracleColumnText',
146
+ description: 'Represents a single column in an OracleCollection.'
147
+ }
148
+ )
149
+ export type TOracleColumnText = typeof OracleColumnText
150
+ export type OracleColumnText = Static<typeof OracleColumnText>
151
+
152
+ export const OracleColumnText2 = RollableColumn(
153
+ 'column_text2',
154
+ Type.Ref(OracleRollableRowText2),
155
+ {
156
+ $id: 'OracleColumnText2'
157
+ }
158
+ )
159
+
160
+ export type TOracleColumnText2 = typeof OracleColumnText2
161
+ export type OracleColumnText2 = Static<typeof OracleColumnText2>
162
+
163
+ export const OracleColumnText3 = RollableColumn(
164
+ 'column_text3',
165
+ Type.Ref(OracleRollableRowText3),
166
+ {
167
+ $id: 'OracleColumnText3'
168
+ }
169
+ )
170
+
171
+ export type TOracleColumnText3 = typeof OracleColumnText3
172
+ export type OracleColumnText3 = Static<typeof OracleColumnText2>
173
+
174
+ export const OracleRollable = Utils.DiscriminatedUnion(
175
+ {
176
+ table_text: OracleTableText,
177
+ table_text2: OracleTableText2,
178
+ table_text3: OracleTableText3,
179
+ column_text: OracleColumnText,
180
+ column_text2: OracleColumnText2,
181
+ column_text3: OracleColumnText3
182
+ },
183
+ 'oracle_type',
184
+ {
185
+ $id: 'OracleRollable',
186
+ description:
187
+ 'A collection of table rows from which random results may be rolled. This may represent a standalone table, or a column in a larger table.'
188
+ }
189
+ )
190
+
191
+ export type OracleRollable = Static<typeof OracleRollable>
192
+ export type TOracleRollable = typeof OracleRollable
193
+
194
+ export const OracleRollableTable = Utils.DiscriminatedUnion(
195
+ {
196
+ table_text: OracleTableText,
197
+ table_text2: OracleTableText2,
198
+ table_text3: OracleTableText3
199
+ },
200
+ 'oracle_type',
201
+ {
202
+ $id: 'OracleRollableTable'
203
+ }
204
+ )
205
+
206
+ export type OracleRollableTable = Static<typeof OracleRollableTable>
207
+ export type TOracleRollableTable = typeof OracleRollableTable