warframe-worldstate-parser 2.23.2 → 2.25.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 (65) hide show
  1. package/lib/Alert.js +8 -8
  2. package/lib/CambionCycle.js +1 -5
  3. package/lib/CetusCycle.js +3 -3
  4. package/lib/ChallengeInstance.js +6 -6
  5. package/lib/ConclaveChallenge.js +2 -5
  6. package/lib/ConstructionProgress.js +4 -2
  7. package/lib/DailyDeal.js +1 -3
  8. package/lib/DarkSector.js +11 -8
  9. package/lib/EarthCycle.js +4 -4
  10. package/lib/Fissure.js +18 -10
  11. package/lib/FlashSale.js +2 -7
  12. package/lib/GlobalUpgrade.js +5 -5
  13. package/lib/Invasion.js +11 -10
  14. package/lib/Kuva.js +16 -10
  15. package/lib/Mission.js +31 -21
  16. package/lib/News.js +13 -15
  17. package/lib/Nightwave.js +7 -4
  18. package/lib/NightwaveChallenge.js +2 -4
  19. package/lib/PersistentEnemy.js +1 -3
  20. package/lib/Reward.js +64 -60
  21. package/lib/SentientOutpost.js +7 -8
  22. package/lib/Simaris.js +5 -3
  23. package/lib/Sortie.js +22 -16
  24. package/lib/SortieVariant.js +17 -18
  25. package/lib/SteelPathOffering.js +1 -0
  26. package/lib/SyndicateJob.js +20 -11
  27. package/lib/SyndicateMission.js +6 -6
  28. package/lib/VallisCycle.js +2 -2
  29. package/lib/VoidTrader.js +9 -13
  30. package/lib/WeeklyChallenge.js +4 -3
  31. package/lib/WorldEvent.js +23 -29
  32. package/lib/WorldState.js +50 -28
  33. package/lib/WorldstateObject.js +35 -12
  34. package/lib/ZarimanCycle.js +141 -0
  35. package/lib/timeDate.js +13 -12
  36. package/lib/translation.js +47 -38
  37. package/package.json +3 -118
  38. package/types/lib/Alert.d.ts +1 -1
  39. package/types/lib/CambionCycle.d.ts +9 -0
  40. package/types/lib/CetusCycle.d.ts +1 -0
  41. package/types/lib/ConclaveChallenge.d.ts +1 -1
  42. package/types/lib/DailyDeal.d.ts +1 -1
  43. package/types/lib/DarkSector.d.ts +1 -1
  44. package/types/lib/EarthCycle.d.ts +1 -0
  45. package/types/lib/Fissure.d.ts +11 -10
  46. package/types/lib/FlashSale.d.ts +1 -1
  47. package/types/lib/GlobalUpgrade.d.ts +1 -1
  48. package/types/lib/Invasion.d.ts +4 -4
  49. package/types/lib/Kuva.d.ts +1 -6
  50. package/types/lib/Mission.d.ts +11 -4
  51. package/types/lib/News.d.ts +4 -4
  52. package/types/lib/Nightwave.d.ts +2 -1
  53. package/types/lib/NightwaveChallenge.d.ts +7 -1
  54. package/types/lib/PersistentEnemy.d.ts +1 -1
  55. package/types/lib/SentientOutpost.d.ts +1 -1
  56. package/types/lib/Sortie.d.ts +10 -16
  57. package/types/lib/SortieVariant.d.ts +14 -20
  58. package/types/lib/SyndicateMission.d.ts +6 -1
  59. package/types/lib/VallisCycle.d.ts +1 -0
  60. package/types/lib/VoidTrader.d.ts +1 -1
  61. package/types/lib/WorldEvent.d.ts +3 -3
  62. package/types/lib/WorldState.d.ts +5 -1
  63. package/types/lib/WorldstateObject.d.ts +43 -11
  64. package/types/lib/ZarimanCycle.d.ts +56 -0
  65. package/types/main.d.ts +1 -1
@@ -63,7 +63,9 @@ const getBountyRewards = async (i18n, isVault, raw) => {
63
63
  ({ location, locationWRot } = determineLocation(i18n, isVault, raw));
64
64
  }
65
65
  const url = `${apiBase}/drops/search/${encodeURIComponent(location)}?grouped_by=location`;
66
- const reply = await fetch(url).then((res) => res.json()).catch(() => {}); // swallow errors
66
+ const reply = await fetch(url)
67
+ .then((res) => res.json())
68
+ .catch(() => {}); // swallow errors
67
69
  const pool = (reply || {})[locationWRot];
68
70
  if (!pool) {
69
71
  return ['Pattern Mismatch. Results inaccurate.'];
@@ -72,6 +74,7 @@ const getBountyRewards = async (i18n, isVault, raw) => {
72
74
  if (results) {
73
75
  return Array.from(new Set(results.map((result) => result.item)));
74
76
  }
77
+ /* istanbul ignore next */
75
78
  return [];
76
79
  };
77
80
 
@@ -91,28 +94,34 @@ class SyndicateJob extends WorldstateObject {
91
94
  * @param {string} locale Locale to use for translations
92
95
  */
93
96
  constructor(data, expiry, { translator, timeDate, locale }) {
94
- super({ _id: { $oid: data.JobCurrentVersion ? data.JobCurrentVersion.$oid : `${(data.jobType || '').split('/').slice(-1)[0]}${expiry.getTime()}` } }, { timeDate });
97
+ super(
98
+ {
99
+ _id: {
100
+ $oid: data.JobCurrentVersion
101
+ ? data.JobCurrentVersion.$oid
102
+ : `${(data.jobType || '').split('/').slice(-1)[0]}${expiry.getTime()}`,
103
+ },
104
+ },
105
+ { timeDate }
106
+ );
95
107
 
96
108
  /**
97
109
  * Array of strings describing rewards
98
110
  * @type {Array.<String>}
99
111
  */
100
112
  this.rewardPool = [];
101
- getBountyRewards(data.rewards, data.isVault, data)
102
- .then((rewards) => {
103
- this.rewardPool = rewards;
104
- });
113
+ getBountyRewards(data.rewards, data.isVault, data).then((rewards) => {
114
+ this.rewardPool = rewards;
115
+ });
105
116
 
106
- const chamber = ((data.locationTag || '')
107
- .match(/[A-Z]+(?![a-z])|[A-Z]?[a-z]+|\d+/g) || [])
108
- .join(' ');
117
+ const chamber = ((data.locationTag || '').match(/[A-Z]+(?![a-z])|[A-Z]?[a-z]+|\d+/g) || []).join(' ');
109
118
 
110
119
  /**
111
120
  * The type of job this is
112
121
  * @type {String}
113
122
  */
114
- this.type = translator.languageString(data.jobType, locale)
115
- || `${data.isVault ? 'Isolation Vault' : ''} ${chamber}`;
123
+ this.type =
124
+ translator.languageString(data.jobType, locale) || `${data.isVault ? 'Isolation Vault' : ''} ${chamber}`;
116
125
 
117
126
  /**
118
127
  * Array of enemy levels
@@ -16,13 +16,14 @@ class SyndicateMission extends WorldstateObject {
16
16
  * @param {TimeDateFunctions} deps.timeDate The time and date functions
17
17
  * @param {string} deps.locale Locale to use for translations
18
18
  */
19
- constructor(data, {
20
- mdConfig, translator, timeDate, locale,
21
- }) {
19
+ constructor(data, { mdConfig, translator, timeDate, locale }) {
22
20
  super(data, { timeDate });
23
21
 
24
22
  const deps = {
25
- mdConfig, translator, timeDate, locale,
23
+ mdConfig,
24
+ translator,
25
+ timeDate,
26
+ locale,
26
27
  };
27
28
 
28
29
  /**
@@ -113,8 +114,7 @@ class SyndicateMission extends WorldstateObject {
113
114
  toString() {
114
115
  if (this.nodes.length > 0) {
115
116
  const missions = this.nodes.map((n) => ` \u2022${n.toString()}`).join(this.mdConfig.lineEnd);
116
- return `[${this.getETAString()}] ${this.syndicate} currently has missions on: `
117
- + `${this.mdConfig.lineEnd}${missions}`;
117
+ return `[${this.getETAString()}] ${this.syndicate} currently has missions on:${this.mdConfig.lineEnd}${missions}`;
118
118
  }
119
119
 
120
120
  return `No missions available for ${this.syndicate}`;
@@ -21,7 +21,7 @@ function getCurrentCycle() {
21
21
  toNextMinor = toNextFull - coldTime;
22
22
  }
23
23
  const milliAtNext = Date.now() + toNextMinor;
24
- const milliAtPrev = (Date.now() + toNextFull) - (state === 'warm' ? loopTime : coldTime);
24
+ const milliAtPrev = Date.now() + toNextFull - (state === 'warm' ? loopTime : coldTime);
25
25
  const timeAtPrevious = new Date(milliAtPrev);
26
26
  timeAtPrevious.setSeconds(0);
27
27
 
@@ -104,7 +104,7 @@ class VallisCycle extends WorldstateObject {
104
104
 
105
105
  this.id = `vallisCycle${ec.timeAtPrevious.getTime()}`;
106
106
 
107
- this.shortString = `${this.timeLeft.replace(/\s\d*s/ig, '')} to ${this.isWarm ? 'Cold' : 'Warm'}`;
107
+ this.shortString = `${this.timeLeft.replace(/\s\d*s/gi, '')} to ${this.isWarm ? 'Cold' : 'Warm'}`;
108
108
  }
109
109
 
110
110
  /**
package/lib/VoidTrader.js CHANGED
@@ -17,9 +17,7 @@ class VoidTrader extends WorldstateObject {
17
17
  * @param {TimeDateFunctions} deps.timeDate The time and date functions
18
18
  * @param {string} deps.locale Locale to use for translations
19
19
  */
20
- constructor(data, {
21
- mdConfig, translator, timeDate, locale,
22
- }) {
20
+ constructor(data, { mdConfig, translator, timeDate, locale }) {
23
21
  super(data, { timeDate });
24
22
 
25
23
  /**
@@ -54,7 +52,7 @@ class VoidTrader extends WorldstateObject {
54
52
  * The void trader's name
55
53
  * @type {string}
56
54
  */
57
- this.character = data.Character ? data.Character.replace('Baro\'Ki Teel', 'Baro Ki\'Teer') : '';
55
+ this.character = data.Character ? data.Character.replace("Baro'Ki Teel", "Baro Ki'Teer") : '';
58
56
 
59
57
  /**
60
58
  * The node at which the Void Trader appears
@@ -66,9 +64,7 @@ class VoidTrader extends WorldstateObject {
66
64
  * The trader's inventory
67
65
  * @type {VoidTraderItem[]}
68
66
  */
69
- this.inventory = data.Manifest
70
- ? data.Manifest.map((i) => new VoidTraderItem(i, { translator, locale }))
71
- : [];
67
+ this.inventory = data.Manifest ? data.Manifest.map((i) => new VoidTraderItem(i, { translator, locale })) : [];
72
68
 
73
69
  /**
74
70
  * Pseudo Identifier for identifying changes in inventory
@@ -99,8 +95,7 @@ class VoidTrader extends WorldstateObject {
99
95
  this.initialStart = timeDate.parseDate(data.InitialStartDate);
100
96
  this.completed = data.Completed;
101
97
  this.schedule = data.ScheduleInfo
102
- ? data.ScheduleInfo
103
- .map((i) => new VoidTraderSchedule(i, { timeDate, translator, locale }))
98
+ ? data.ScheduleInfo.map((i) => new VoidTraderSchedule(i, { timeDate, translator, locale }))
104
99
  : [];
105
100
  }
106
101
 
@@ -109,8 +104,7 @@ class VoidTrader extends WorldstateObject {
109
104
  * @returns {boolean}
110
105
  */
111
106
  isActive() {
112
- return (this.timeDate.fromNow(this.activation) < 0)
113
- && (this.timeDate.fromNow(this.expiry) > 0);
107
+ return this.timeDate.fromNow(this.activation) < 0 && this.timeDate.fromNow(this.expiry) > 0;
114
108
  }
115
109
 
116
110
  /**
@@ -137,8 +131,10 @@ class VoidTrader extends WorldstateObject {
137
131
  if (!this.isActive()) {
138
132
  const timeDelta = this.timeDate.fromNow(this.activation);
139
133
  const nextArrivalTime = this.timeDate.timeDeltaToString(timeDelta);
140
- return `${this.mdConfig.codeMulti}${this.character} is not here yet, he will arrive in `
141
- + `${nextArrivalTime} at ${this.location}${this.mdConfig.blockEnd}`;
134
+ return (
135
+ `${this.mdConfig.codeMulti}${this.character} is not here yet, he will arrive in ` +
136
+ `${nextArrivalTime} at ${this.location}${this.mdConfig.blockEnd}`
137
+ );
142
138
  }
143
139
 
144
140
  const inventoryString = this.inventory
@@ -18,8 +18,7 @@ class WeeklyChallenge extends WorldstateObject {
18
18
  constructor(data, { timeDate, translator }) {
19
19
  super(data, { timeDate });
20
20
 
21
- this.challenges = data.Challenges
22
- .map((challengeData) => new ChallengeInstance(challengeData, { translator }));
21
+ this.challenges = data.Challenges.map((challengeData) => new ChallengeInstance(challengeData, { translator }));
23
22
  }
24
23
 
25
24
  /**
@@ -27,7 +26,9 @@ class WeeklyChallenge extends WorldstateObject {
27
26
  * @returns {string}
28
27
  */
29
28
  toString() {
30
- return `Starts: ${this.getStartString()}\nEnds: ${this.getEndString()}\nChallenges:\n${this.challenges.map((challenge) => `\t${challenge.toString()}`).join('\n')}`;
29
+ return `Starts: ${this.getStartString()}\nEnds: ${this.getEndString()}\nChallenges:\n${this.challenges
30
+ .map((challenge) => `\t${challenge.toString()}`)
31
+ .join('\n')}`;
31
32
  }
32
33
  }
33
34
 
package/lib/WorldEvent.js CHANGED
@@ -36,13 +36,15 @@ class WorldEvent extends WorldstateObject {
36
36
  * @param {Reward} deps.Reward The Reward parser
37
37
  * @param {string} deps.locale Locale to use for translations
38
38
  */
39
- constructor(data, {
40
- mdConfig, translator, timeDate, Reward, locale,
41
- }) {
39
+ constructor(data, { mdConfig, translator, timeDate, Reward, locale }) {
42
40
  super(data, { timeDate });
43
41
 
44
42
  const opts = {
45
- translator, mdConfig, Reward, timeDate, locale,
43
+ translator,
44
+ mdConfig,
45
+ Reward,
46
+ timeDate,
47
+ locale,
46
48
  };
47
49
 
48
50
  /**
@@ -118,9 +120,7 @@ class WorldEvent extends WorldstateObject {
118
120
  * The other nodes where the event takes place
119
121
  * @type {string[]}
120
122
  */
121
- this.concurrentNodes = data.ConcurrentNodes
122
- ? data.ConcurrentNodes.map((n) => translator.node(n), locale)
123
- : [];
123
+ this.concurrentNodes = data.ConcurrentNodes ? data.ConcurrentNodes.map((n) => translator.node(n), locale) : [];
124
124
 
125
125
  /**
126
126
  * The victim node
@@ -132,16 +132,14 @@ class WorldEvent extends WorldstateObject {
132
132
  * The score description
133
133
  * @type {?string}
134
134
  */
135
- this.scoreLocTag = data.Fomorian
136
- ? 'Fomorian Assault Score'
137
- : translator.languageString(data.ScoreLocTag, locale);
135
+ this.scoreLocTag = data.Fomorian ? 'Fomorian Assault Score' : translator.languageString(data.ScoreLocTag, locale);
138
136
 
139
137
  /**
140
138
  * The event's rewards
141
139
  * @type {Reward[]}
142
140
  */
143
141
  this.rewards = Object.keys(data)
144
- .filter((k) => (k.includes('Reward') || k.includes('reward')))
142
+ .filter((k) => k.includes('Reward') || k.includes('reward'))
145
143
  .map((k) => new Reward(data[k], opts));
146
144
 
147
145
  /**
@@ -154,16 +152,14 @@ class WorldEvent extends WorldstateObject {
154
152
  * Health remaining for the target
155
153
  * @type {Number}
156
154
  */
157
- this.health = typeof data.HealthPct !== 'undefined'
158
- ? Number.parseFloat(((data.HealthPct || 0.00) * 100).toFixed(2))
159
- : undefined;
155
+ this.health =
156
+ typeof data.HealthPct !== 'undefined' ? Number.parseFloat(((data.HealthPct || 0.0) * 100).toFixed(2)) : undefined;
160
157
 
161
158
  if (data.JobAffiliationTag) {
162
159
  this.affiliatedWith = translator.syndicate(data.JobAffiliationTag, locale);
163
160
  if (data.Jobs) {
164
161
  this.jobs = (data.Jobs || []).map((j) => new SyndicateJob(j, this.expiry, opts));
165
- this.previousJobs = (data.PreviousJobs || [])
166
- .map((j) => new SyndicateJob(j, this.expiry, opts));
162
+ this.previousJobs = (data.PreviousJobs || []).map((j) => new SyndicateJob(j, this.expiry, opts));
167
163
  }
168
164
  }
169
165
 
@@ -180,7 +176,7 @@ class WorldEvent extends WorldstateObject {
180
176
  this.interimSteps = [];
181
177
 
182
178
  (data.InterimRewards || []).forEach((reward, index) => {
183
- const msg = ((data.InterimRewardMessages || [])[index] || {});
179
+ const msg = (data.InterimRewardMessages || [])[index] || {};
184
180
  this.interimSteps[index] = {
185
181
  goal: Number.parseInt(data.InterimGoals[index], 10),
186
182
  reward: reward ? new Reward(reward, opts) : undefined,
@@ -191,13 +187,14 @@ class WorldEvent extends WorldstateObject {
191
187
  senderIcon: msg.senderIcon,
192
188
  attachments: msg.attachments,
193
189
  },
190
+ // eslint-disable-next-line no-underscore-dangle
194
191
  winnerCount: (data._interimWinnerCounts || [])[index],
195
192
  };
196
193
  });
197
194
 
198
195
  /**
199
196
  * Progress Steps, if any are present
200
- * @type {ProgessStep[]}
197
+ * @type {ProgressStep[]}
201
198
  */
202
199
  this.progressSteps = [];
203
200
 
@@ -213,8 +210,7 @@ class WorldEvent extends WorldstateObject {
213
210
  * Total of all MultiProgress
214
211
  * @type {Number}
215
212
  */
216
- this.progressTotal = Number.parseFloat(data.MultiProgress
217
- .reduce((accumulator, val) => accumulator + val));
213
+ this.progressTotal = Number.parseFloat(data.MultiProgress.reduce((accumulator, val) => accumulator + val));
218
214
  }
219
215
 
220
216
  /**
@@ -237,15 +233,13 @@ class WorldEvent extends WorldstateObject {
237
233
  * Affectors for this mission
238
234
  * @type {string[]}
239
235
  */
240
- this.regionDrops = (data.RegionDrops || [])
241
- .map((drop) => translator.languageString(drop, locale));
236
+ this.regionDrops = (data.RegionDrops || []).map((drop) => translator.languageString(drop, locale));
242
237
 
243
238
  /**
244
239
  * Archwing Drops in effect while this event is active
245
240
  * @type {string[]}
246
241
  */
247
- this.archwingDrops = (data.ArchwingDrops || [])
248
- .map((drop) => translator.languageString(drop, locale));
242
+ this.archwingDrops = (data.ArchwingDrops || []).map((drop) => translator.languageString(drop, locale));
249
243
 
250
244
  this.asString = this.toString();
251
245
 
@@ -285,9 +279,7 @@ class WorldEvent extends WorldstateObject {
285
279
  * @returns {string}
286
280
  */
287
281
  toString() {
288
- let lines = [
289
- `${this.description} : ${this.faction}`,
290
- ];
282
+ let lines = [`${this.description} : ${this.faction}`];
291
283
 
292
284
  if (this.scoreLocTag && this.maximumScore) {
293
285
  lines.push(`${this.scoreLocTag} : ${this.maximumScore}`);
@@ -308,8 +300,10 @@ class WorldEvent extends WorldstateObject {
308
300
  }
309
301
 
310
302
  if (this.affiliatedWith && this.jobs) {
311
- lines.push(`${this.affiliatedWith} will reward you for performing `
312
- + `${this.jobs.map((job) => job.type).join(', ')} job${this.jobs.length > 1 ? 's' : ''}`);
303
+ lines.push(
304
+ `${this.affiliatedWith} will reward you for performing ` +
305
+ `${this.jobs.map((job) => job.type).join(', ')} job${this.jobs.length > 1 ? 's' : ''}`
306
+ );
313
307
  }
314
308
 
315
309
  return lines.join(this.mdConfig.lineEnd);
package/lib/WorldState.js CHANGED
@@ -27,6 +27,7 @@ const EarthCycle = require('./EarthCycle');
27
27
  const CetusCycle = require('./CetusCycle');
28
28
  const ConstructionProgress = require('./ConstructionProgress');
29
29
  const VallisCycle = require('./VallisCycle');
30
+ const ZarimanCycle = require('./ZarimanCycle');
30
31
  const WeeklyChallenge = require('./WeeklyChallenge');
31
32
  const Nightwave = require('./Nightwave');
32
33
  const Kuva = require('./Kuva');
@@ -34,15 +35,11 @@ const SentientOutpost = require('./SentientOutpost');
34
35
  const CambionCycle = require('./CambionCycle');
35
36
  const SteelPathOffering = require('./SteelPathOffering');
36
37
 
37
- /* eslint-disable no-unused-vars */
38
38
  // needed for type declarations
39
- const Dependency = require('./supporting/Dependency');
40
- const ExternalMission = require('./supporting/ExternalMission');
41
39
  const MarkdownSettings = require('./supporting/MarkdownSettings');
42
- /* eslint-enable no-unused-vars */
43
40
 
44
- const safeArray = (arr) => (arr || []);
45
- const safeObj = (obj) => (obj || {});
41
+ const safeArray = (arr) => arr || [];
42
+ const safeObj = (obj) => obj || {};
46
43
 
47
44
  /**
48
45
  * Default Dependency object
@@ -77,11 +74,19 @@ const defaultDeps = {
77
74
  logger: console,
78
75
  };
79
76
 
77
+ /**
78
+ *
79
+ * @param {Object} ParserClass class for parsing data
80
+ * @param {Array<BaseContentObject>} dataArray array of raw data
81
+ * @param {Dependency} deps shared dependency object
82
+ * @param {*} uniqueField field to treat as unique
83
+ * @returns {WorldstateObject}
84
+ */
80
85
  function parseArray(ParserClass, dataArray, deps, uniqueField) {
81
86
  const arr = (dataArray || []).map((d) => new ParserClass(d, deps));
82
87
  if (uniqueField) {
83
88
  const utemp = {};
84
- arr.sort((a, b) => a.id.localeCompare((b.id)));
89
+ arr.sort((a, b) => a.id.localeCompare(b.id));
85
90
  arr.forEach((obj) => {
86
91
  utemp[obj[uniqueField]] = obj;
87
92
  });
@@ -89,6 +94,7 @@ function parseArray(ParserClass, dataArray, deps, uniqueField) {
89
94
  if (Object.prototype.hasOwnProperty.call(obj, 'active')) {
90
95
  return obj.active;
91
96
  }
97
+ /* istanbul ignore next */
92
98
  return true;
93
99
  });
94
100
  }
@@ -126,9 +132,13 @@ module.exports = class WorldState {
126
132
  * The in-game news
127
133
  * @type {Array.<News>}
128
134
  */
129
- this.news = parseArray(deps.News, (data.Events
130
- ? data.Events.filter((e) => typeof e.Messages.find((msg) => msg.LanguageCode === deps.locale) !== 'undefined')
131
- : []), deps);
135
+ this.news = parseArray(
136
+ deps.News,
137
+ data.Events
138
+ ? data.Events.filter((e) => typeof e.Messages.find((msg) => msg.LanguageCode === deps.locale) !== 'undefined')
139
+ : [],
140
+ deps
141
+ );
132
142
 
133
143
  /**
134
144
  * The current events
@@ -158,8 +168,9 @@ module.exports = class WorldState {
158
168
  * The current fissures: 'ActiveMissions' & 'VoidStorms'
159
169
  * @type {Array.<News>}
160
170
  */
161
- this.fissures = parseArray(deps.Fissure, data.ActiveMissions, deps)
162
- .concat(parseArray(deps.Fissure, data.VoidStorms, deps));
171
+ this.fissures = parseArray(deps.Fissure, data.ActiveMissions, deps).concat(
172
+ parseArray(deps.Fissure, data.VoidStorms, deps)
173
+ );
163
174
 
164
175
  /**
165
176
  * The current global upgrades
@@ -221,10 +232,8 @@ module.exports = class WorldState {
221
232
  */
222
233
  this.earthCycle = new EarthCycle(deps);
223
234
 
224
- const cetusSynd = safeArray(data.SyndicateMissions)
225
- .filter((syndicate) => syndicate.Tag === 'CetusSyndicate');
226
- const cetusBountyEnd = timeDate
227
- .parseDate(cetusSynd.length > 0 ? cetusSynd[0].Expiry : { $date: 0 });
235
+ const cetusSynd = safeArray(data.SyndicateMissions).filter((syndicate) => syndicate.Tag === 'CetusSyndicate');
236
+ const cetusBountyEnd = timeDate.parseDate(cetusSynd.length > 0 ? cetusSynd[0].Expiry : { $date: 0 });
228
237
 
229
238
  /**
230
239
  * The current Cetus cycle
@@ -238,28 +247,35 @@ module.exports = class WorldState {
238
247
  */
239
248
  this.cambionCycle = new CambionCycle(this.cetusCycle, deps);
240
249
 
250
+ const zarimanSynd = safeArray(data.SyndicateMissions).filter((syndicate) => syndicate.Tag === 'ZarimanSyndicate');
251
+ const zarimanBountyEnd = timeDate.parseDate(zarimanSynd.length > 0 ? zarimanSynd[0].Expiry : { $date: 0 });
252
+
253
+ /**
254
+ * The current Zariman cycle based off current time
255
+ * @type {ZarimanCycle}
256
+ */
257
+ this.zarimanCycle = new ZarimanCycle(zarimanBountyEnd, deps);
258
+
241
259
  /**
242
260
  * Weekly challenges
243
261
  * @type {Array.<WeeklyChallenge>}
244
262
  */
245
- this.weeklyChallenges = data.WeeklyChallenges
246
- ? new deps.WeeklyChallenge(data.WeeklyChallenges, deps)
247
- : [];
263
+ this.weeklyChallenges = data.WeeklyChallenges ? new deps.WeeklyChallenge(data.WeeklyChallenges, deps) : [];
248
264
 
249
- const projectPCTwithOid = data.ProjectPct ? {
250
- ProjectPct: data.ProjectPct,
251
- _id: {
252
- $oid: `${Date.now()}${data.ProjectPct[0]}`,
253
- },
254
- } : undefined;
265
+ const projectPCTwithOid = data.ProjectPct
266
+ ? {
267
+ ProjectPct: data.ProjectPct,
268
+ _id: {
269
+ $oid: `${Date.now()}${data.ProjectPct[0]}`,
270
+ },
271
+ }
272
+ : undefined;
255
273
 
256
274
  /**
257
275
  * The Current construction progress for Fomorians/Razorback/etc.
258
276
  * @type {ConstructionProgress}
259
277
  */
260
- this.constructionProgress = projectPCTwithOid
261
- ? new ConstructionProgress(projectPCTwithOid, deps)
262
- : {};
278
+ this.constructionProgress = projectPCTwithOid ? new ConstructionProgress(projectPCTwithOid, deps) : {};
263
279
 
264
280
  /**
265
281
  * The current Orb Vallis cycle state
@@ -303,5 +319,11 @@ module.exports = class WorldState {
303
319
  this.steelPath = new SteelPathOffering(deps);
304
320
 
305
321
  [this.vaultTrader] = parseArray(deps.VoidTrader, data.PrimeVaultTraders, deps);
322
+
323
+ /**
324
+ * The current archon hunt
325
+ * @type {Sortie}
326
+ */
327
+ [this.archonHunt] = parseArray(deps.Sortie, data.LiteSorties, deps);
306
328
  }
307
329
  };
@@ -1,18 +1,44 @@
1
1
  'use strict';
2
2
 
3
3
  /**
4
- * Represents a generic ojbect from Worldstate
4
+ * @typedef {Object} Identifier
5
+ * @property {string} $id older identifier schema
6
+ * @property {string} $oid newer global identifier schema
5
7
  */
6
- class WorldstateObject {
8
+ /**
9
+ * @typedef {Object} LegacyTimestamp
10
+ * @property {number} sec second-based timestamp
11
+ */
12
+ /**
13
+ * @typedef {Object} Timestamp
14
+ * @property {number} $numberLong millisecond-based timestamp
15
+ */
16
+ /**
17
+ * @typedef {Object} ContentTimestamp
18
+ * @property {LegacyTimestamp|Timestamp} $date timestamp number wrapper
19
+ */
20
+ /**
21
+ * @typedef {Object} BaseContentObject
22
+ * @property {Identifier} _id
23
+ * @property {ContentTimestamp} Activation
24
+ * @property {ContentTimestamp} Expiry
25
+ */
26
+
27
+ /**
28
+ * Represents a generic object from Worldstate
29
+ */
30
+ module.exports = class WorldstateObject {
7
31
  /**
8
- * @param {Object} data The object data
32
+ * @param {BaseContentObject} data The object data
33
+ * @param {TimeDateFunctions} timeDate time date functions
9
34
  */
10
35
  constructor(data, { timeDate }) {
11
36
  /**
12
37
  * The object's id field
13
- * @type {string}
38
+ * @type {Identifier.$id|Identifier.$oid}
14
39
  */
15
- this.id = data._id ? (data._id.$oid || data._id.$id) : undefined;
40
+ // eslint-disable-next-line no-underscore-dangle
41
+ this.id = data._id ? data._id.$oid || data._id.$id : undefined;
16
42
 
17
43
  /**
18
44
  * The time and date functions
@@ -47,7 +73,7 @@ class WorldstateObject {
47
73
 
48
74
  if (data.Activation && data.Expiry) {
49
75
  /**
50
- * Whether or not the void trader is active (at time of object creation)
76
+ * Whether the void trader is active (at time of object creation)
51
77
  * @type {boolean}
52
78
  */
53
79
  this.active = this.isActive();
@@ -63,12 +89,11 @@ class WorldstateObject {
63
89
  }
64
90
 
65
91
  /**
66
- * Get whether or not the trader is currently active
92
+ * Get whether the trader is currently active
67
93
  * @returns {boolean}
68
94
  */
69
95
  isActive() {
70
- return (this.timeDate.fromNow(this.activation) < 0)
71
- && (this.timeDate.fromNow(this.expiry) > 0);
96
+ return this.timeDate.fromNow(this.activation) < 0 && this.timeDate.fromNow(this.expiry) > 0;
72
97
  }
73
98
 
74
99
  /**
@@ -86,6 +111,4 @@ class WorldstateObject {
86
111
  getEndString() {
87
112
  return this.timeDate.timeDeltaToString(this.timeDate.fromNow(this.expiry));
88
113
  }
89
- }
90
-
91
- module.exports = WorldstateObject;
114
+ };