coh-content-db 2.0.0-rc.16 → 2.0.0-rc.18

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.
@@ -5,6 +5,7 @@ import { ContactData } from '../api/contact-data'
5
5
  import { Location } from './location'
6
6
  import { MoralityList } from './morality-list'
7
7
  import { coalesceToArray } from '../util/coalesce-to-array'
8
+ import { LevelRange } from './level-range'
8
9
 
9
10
  export class Contact {
10
11
  /**
@@ -27,7 +28,7 @@ export class Contact {
27
28
  /**
28
29
  * The character moralities that this contact will interact with.
29
30
  */
30
- readonly morality?: MoralityList
31
+ readonly morality: MoralityList
31
32
 
32
33
  /**
33
34
  * The location of this contact.
@@ -37,7 +38,7 @@ export class Contact {
37
38
  /**
38
39
  * The level range this contact will offer missions for.
39
40
  */
40
- readonly levelRange?: [number, number?]
41
+ readonly levelRange?: LevelRange
41
42
 
42
43
  /**
43
44
  * Freeform notes or tips about the contact.
@@ -55,7 +56,7 @@ export class Contact {
55
56
  this.title = data.title
56
57
  this.morality = new MoralityList(coalesceToArray(data.morality))
57
58
  this.location = data.location
58
- this.levelRange = data.levelRange
59
+ this.levelRange = data.levelRange ? new LevelRange(data.levelRange) : undefined
59
60
  this.notes = data.notes
60
61
  this.links = data.links ?? []
61
62
  }
@@ -0,0 +1,15 @@
1
+ import { LevelRangeData } from '../api/level-range-data'
2
+
3
+ export class LevelRange {
4
+ readonly min: number
5
+ readonly max?: number
6
+
7
+ constructor(value: LevelRangeData) {
8
+ if (Array.isArray(value)) {
9
+ this.min = value[0]
10
+ this.max = value[1] === undefined ? undefined : value[1]
11
+ } else {
12
+ this.min = value
13
+ }
14
+ }
15
+ }
@@ -5,6 +5,7 @@ import { MissionData } from '../api/mission-data'
5
5
  import { Key } from './key'
6
6
  import { MoralityList } from './morality-list'
7
7
  import { coalesceToArray } from '../util/coalesce-to-array'
8
+ import { LevelRange } from './level-range'
8
9
 
9
10
  export class Mission {
10
11
  /**
@@ -39,7 +40,7 @@ export class Mission {
39
40
  /**
40
41
  * The level range this mission is available for.
41
42
  */
42
- readonly levelRange?: [number, number?]
43
+ readonly levelRange?: LevelRange
43
44
 
44
45
  /**
45
46
  * Freeform notes or tips about the mission.
@@ -62,19 +63,19 @@ export class Mission {
62
63
  readonly id: string
63
64
 
64
65
  /**
65
- * The level range this mission appears under as a Flashback. Leave undefined if the same as the base mission.
66
+ * The level range this mission appears under as a Flashback.
66
67
  */
67
- readonly levelRange?: [number, number?]
68
+ readonly levelRange?: LevelRange
68
69
 
69
70
  /**
70
- * The name as it appears in the Flashback list. Leave undefined if the same as the base mission.
71
+ * The name as it appears in the Flashback list.
71
72
  */
72
- readonly name?: string
73
+ readonly name: string
73
74
 
74
75
  /**
75
- * The character moralities that the mission will appear for in the Flashback list. Leave undefined if the same as the base mission.
76
+ * The character moralities that the mission will appear for in the Flashback list.
76
77
  */
77
- readonly morality?: MoralityList
78
+ readonly morality: MoralityList
78
79
 
79
80
  /**
80
81
  * Freeform notes or tips about the Flashback version of the mission.
@@ -88,7 +89,7 @@ export class Mission {
88
89
  this.type = data.type
89
90
  this.morality = new MoralityList(coalesceToArray(data.morality))
90
91
  this.contactKeys = coalesceToArray(data.contactKeys)
91
- this.levelRange = data.levelRange
92
+ this.levelRange = data.levelRange ? new LevelRange(data.levelRange) : undefined
92
93
  this.notes = data.notes
93
94
  this.links = data.links ?? []
94
95
  this.flashback = createFlashback(data)
@@ -99,7 +100,7 @@ function createFlashback(data: MissionData): Mission['flashback'] {
99
100
  if (!data.flashback) return undefined
100
101
  return {
101
102
  id: data.flashback.id,
102
- levelRange: data.flashback.levelRange ?? data.levelRange,
103
+ levelRange: data.flashback.levelRange ? new LevelRange(data.flashback.levelRange) : undefined,
103
104
  name: data.flashback.name ?? data.name,
104
105
  morality: new MoralityList(coalesceToArray(data.flashback.morality ?? data.morality)),
105
106
  notes: data.flashback.notes,
@@ -0,0 +1,10 @@
1
+ import { SetTitleData } from '../api/set-title-data'
2
+
3
+ export class SetTitleIds {
4
+ readonly primal: number
5
+ readonly praetorian?: number
6
+
7
+ constructor(value: SetTitleData) {
8
+ [this.primal, this.praetorian] = value
9
+ }
10
+ }
@@ -1,6 +1,11 @@
1
1
  import { Link } from '../api/link'
2
2
  import { ZoneData } from '../api/zone-data'
3
3
  import { Key } from './key'
4
+ import { MoralityList } from './morality-list'
5
+ import { coalesceToArray } from '../util/coalesce-to-array'
6
+ import { ZoneType } from '../api/zone-type'
7
+ import { MarkdownString } from '../api/markdown-string'
8
+ import { LevelRange } from './level-range'
4
9
 
5
10
  export class Zone {
6
11
  /**
@@ -15,6 +20,26 @@ export class Zone {
15
20
  */
16
21
  readonly name: string
17
22
 
23
+ /**
24
+ * The type of zone.
25
+ */
26
+ readonly type: ZoneType
27
+
28
+ /**
29
+ * The character moralities that this zone is accessible by.
30
+ */
31
+ readonly morality: MoralityList
32
+
33
+ /**
34
+ * The level range this zone is recommended for.
35
+ */
36
+ readonly levelRange?: LevelRange
37
+
38
+ /**
39
+ * Freeform notes or tips about the zone.
40
+ */
41
+ readonly notes?: MarkdownString
42
+
18
43
  /**
19
44
  * List of external links. Wiki, forums, etc.
20
45
  */
@@ -23,6 +48,10 @@ export class Zone {
23
48
  constructor(data: ZoneData) {
24
49
  this.key = new Key(data.key).value
25
50
  this.name = data.name
51
+ this.type = data.type
52
+ this.morality = new MoralityList(coalesceToArray(data.morality))
53
+ this.levelRange = data.levelRange ? new LevelRange(data.levelRange) : undefined
54
+ this.notes = data.notes
26
55
  this.links = data.links ?? []
27
56
  }
28
57
  }
package/src/main/index.ts CHANGED
@@ -12,12 +12,16 @@ export * from './api/contact-data'
12
12
  export * from './api/enhancement-category'
13
13
  export * from './api/link'
14
14
  export * from './api/location-data'
15
+ export * from './api/level-range-data'
15
16
  export * from './api/markdown-string'
16
17
  export * from './api/mission-data'
18
+ export * from './api/mission-flashback-data'
17
19
  export * from './api/mission-type'
18
20
  export * from './api/morality'
21
+ export * from './api/set-title-data'
19
22
  export * from './api/sex'
20
23
  export * from './api/zone-data'
24
+ export * from './api/zone-type'
21
25
 
22
26
  // DB
23
27
  export * from './db/alignment-list'
@@ -32,9 +36,11 @@ export * from './db/coh-content-database'
32
36
  export * from './db/contact'
33
37
  export * from './db/key'
34
38
  export * from './db/location'
39
+ export * from './db/level-range'
35
40
  export * from './db/mission'
36
41
  export * from './db/morality-list'
37
42
  export * from './db/paged'
43
+ export * from './db/set-title-ids'
38
44
  export * from './db/zone'
39
45
 
40
46
  // UTILS
@@ -4,5 +4,6 @@ import { defineFixture } from 'efate'
4
4
  export const zoneDataFixture = defineFixture<ZoneData>((t) => {
5
5
  t.key.as(index => `zone-${index}`)
6
6
  t.name.as(index => `Zone ${index}`)
7
+ t.type.withValue('city')
7
8
  t.links?.as(() => [{ title: 'foo', href: 'https://nouri.org' }])
8
9
  })
@@ -152,12 +152,14 @@ describe(Badge.name, () => {
152
152
  describe('setTitle', () => {
153
153
  test('should be set from the data', () => {
154
154
  const badge = new Badge(badgeDataFixture.create({ setTitleId: [123, 456] }))
155
- expect(badge.setTitleId).toStrictEqual([123, 456])
155
+ expect(badge.setTitleId?.primal).toEqual(123)
156
+ expect(badge.setTitleId?.praetorian).toEqual(456)
156
157
  })
157
158
 
158
159
  test('should treat the praetorian id as optional', () => {
159
160
  const badge = new Badge(badgeDataFixture.create({ setTitleId: [123] }))
160
- expect(badge.setTitleId).toStrictEqual([123])
161
+ expect(badge.setTitleId?.primal).toEqual(123)
162
+ expect(badge.setTitleId?.praetorian).toBeUndefined()
161
163
  })
162
164
 
163
165
  test('should be optional', () => {
@@ -62,7 +62,8 @@ describe(Contact.name, () => {
62
62
  describe('levelRange', () => {
63
63
  test(`should be set from the data`, () => {
64
64
  const contact = new Contact(contactDataFixture.create({ levelRange: [1, 2] }))
65
- expect(contact.levelRange).toStrictEqual([1, 2])
65
+ expect(contact?.levelRange?.min).toEqual(1)
66
+ expect(contact?.levelRange?.max).toEqual(2)
66
67
  })
67
68
 
68
69
  test(`should be optional`, () => {
@@ -0,0 +1,47 @@
1
+ import { LevelRange } from '../../main'
2
+
3
+ describe(LevelRange.name, () => {
4
+ describe('Constructor', () => {
5
+ test('should accept a full array (5-10)', () => {
6
+ const range = new LevelRange([5, 10])
7
+ expect(range).toBeDefined()
8
+ expect(range.min).toEqual(5)
9
+ expect(range.max).toEqual(10)
10
+ })
11
+
12
+ test('should accept a partial array (15+)', () => {
13
+ const range = new LevelRange([15])
14
+ expect(range).toBeDefined()
15
+ expect(range.min).toEqual(15)
16
+ expect(range.max).toBeUndefined()
17
+ })
18
+
19
+ test('should not coalesce a explicit max of 50 (20-50)', () => {
20
+ const range = new LevelRange([20, 50])
21
+ expect(range).toBeDefined()
22
+ expect(range.min).toEqual(20)
23
+ expect(range.max).toEqual(50)
24
+ })
25
+
26
+ test('should accept a single-level range (1-1)', () => {
27
+ const range = new LevelRange([1, 1])
28
+ expect(range).toBeDefined()
29
+ expect(range.min).toEqual(1)
30
+ expect(range.max).toEqual(1)
31
+ })
32
+
33
+ test('should accept a zero value (0-0)', () => {
34
+ const range = new LevelRange([0, 0])
35
+ expect(range).toBeDefined()
36
+ expect(range.min).toEqual(0)
37
+ expect(range.max).toEqual(0)
38
+ })
39
+
40
+ test('should accept a number (5+)', () => {
41
+ const range = new LevelRange(5)
42
+ expect(range).toBeDefined()
43
+ expect(range.min).toEqual(5)
44
+ expect(range.max).toBeUndefined()
45
+ })
46
+ })
47
+ })
@@ -56,8 +56,9 @@ describe(Mission.name, () => {
56
56
 
57
57
  describe('levelRange', () => {
58
58
  test(`should be set from the data`, () => {
59
- const mission = new Mission(missionDataFixture.create({ levelRange: [1, 2] }))
60
- expect(mission.levelRange).toStrictEqual([1, 2])
59
+ const mission = new Mission(missionDataFixture.create({ levelRange: 25 }))
60
+ expect(mission?.levelRange?.min).toEqual(25)
61
+ expect(mission?.levelRange?.max).toBeUndefined()
61
62
  })
62
63
 
63
64
  test(`should be optional`, () => {
@@ -105,13 +106,14 @@ describe(Mission.name, () => {
105
106
 
106
107
  describe('levelRange', () => {
107
108
  test(`should be set from the data`, () => {
108
- const mission = new Mission(missionDataFixture.create({ flashback: { levelRange: [1, 2] } }))
109
- expect(mission.flashback?.levelRange).toStrictEqual([1, 2])
109
+ const mission = new Mission(missionDataFixture.create({ flashback: { levelRange: [1, 20] } }))
110
+ expect(mission.flashback?.levelRange?.min).toEqual(1)
111
+ expect(mission.flashback?.levelRange?.max).toEqual(20)
110
112
  })
111
113
 
112
- test(`should default to the mission value`, () => {
114
+ test(`should *not* default to the mission value due to Ouro level grouping`, () => {
113
115
  const mission = new Mission(missionDataFixture.create({ levelRange: [1, 2], flashback: missionFlashbackDataFixture.omit('levelRange').create() }))
114
- expect(mission.flashback?.levelRange).toStrictEqual([1, 2])
116
+ expect(mission.flashback?.levelRange).toBeUndefined()
115
117
  })
116
118
 
117
119
  test(`should be optional`, () => {
@@ -29,7 +29,7 @@ describe(MoralityList.name, () => {
29
29
  expect(new MoralityList().items).toStrictEqual(['hero', 'vigilante', 'villain', 'rogue', 'resistance', 'loyalist'])
30
30
  })
31
31
 
32
- test('should treat empty as no values', () => {
32
+ test('should treat explicit empty as no values', () => {
33
33
  expect(new MoralityList([]).items).toStrictEqual([])
34
34
  })
35
35
  })
@@ -0,0 +1,19 @@
1
+ import { SetTitleIds } from '../../main'
2
+
3
+ describe(SetTitleIds.name, () => {
4
+ describe('Constructor', () => {
5
+ test('should accept both primal and praetorian values', () => {
6
+ const ids = new SetTitleIds([5, 10])
7
+ expect(ids).toBeDefined()
8
+ expect(ids.primal).toEqual(5)
9
+ expect(ids.praetorian).toEqual(10)
10
+ })
11
+
12
+ test('should accept primal only', () => {
13
+ const ids = new SetTitleIds([1])
14
+ expect(ids).toBeDefined()
15
+ expect(ids.primal).toEqual(1)
16
+ expect(ids.praetorian).toBeUndefined()
17
+ })
18
+ })
19
+ })
@@ -22,6 +22,51 @@ describe(Zone.name, () => {
22
22
  })
23
23
  })
24
24
 
25
+ describe('type', () => {
26
+ test(`should be set from the data`, () => {
27
+ const zone = new Zone(zoneDataFixture.create({ type: 'city' }))
28
+ expect(zone.type).toEqual('city')
29
+ })
30
+ })
31
+
32
+ describe('morality', () => {
33
+ test(`should be set from the data`, () => {
34
+ const zone = new Zone(zoneDataFixture.create({ morality: ['hero'] }))
35
+ expect(zone.morality?.hero).toBeTruthy()
36
+ expect(zone.morality?.vigilante).toBeFalsy()
37
+ })
38
+
39
+ test(`should be optional`, () => {
40
+ const zone = new Zone(zoneDataFixture.omit('morality').create())
41
+ expect(zone.morality?.all).toBeTruthy()
42
+ })
43
+ })
44
+
45
+ describe('levelRange', () => {
46
+ test(`should be set from the data`, () => {
47
+ const zone = new Zone(zoneDataFixture.create({ levelRange: [10] }))
48
+ expect(zone.levelRange?.min).toEqual(10)
49
+ expect(zone.levelRange?.max).toBeUndefined()
50
+ })
51
+
52
+ test(`should be optional`, () => {
53
+ const zone = new Zone(zoneDataFixture.omit('levelRange').create())
54
+ expect(zone.levelRange).toBeUndefined()
55
+ })
56
+ })
57
+
58
+ describe('notes', () => {
59
+ test(`should be set from the data`, () => {
60
+ const zone = new Zone(zoneDataFixture.create({ notes: 'foo' }))
61
+ expect(zone.notes).toEqual('foo')
62
+ })
63
+
64
+ test(`should be optional`, () => {
65
+ const zone = new Zone(zoneDataFixture.omit('notes').create())
66
+ expect(zone.notes).toBeUndefined()
67
+ })
68
+ })
69
+
25
70
  describe('links', () => {
26
71
  test(`should be set from the data`, () => {
27
72
  const zone = new Zone(zoneDataFixture.create({ links: [{ title: 'foo', href: 'bar' }] }))