clashofclans.js 3.5.2-dev.50a7e99 → 3.5.4-dev.074d698

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.
@@ -54,6 +54,16 @@ export declare class Util extends null {
54
54
  endTime: Date;
55
55
  seasonId: string;
56
56
  };
57
+ static getTournamentWindow(timestamp?: Date): {
58
+ id: string;
59
+ startTime: Date;
60
+ endTime: Date;
61
+ };
62
+ static getTournamentWindowById(id: string): {
63
+ id: string;
64
+ startTime: Date;
65
+ endTime: Date;
66
+ };
57
67
  static allSettled<T>(values: Promise<T>[]): Promise<T[]>;
58
68
  static delay(ms: number): Promise<unknown>;
59
69
  }
package/dist/util/Util.js CHANGED
@@ -169,9 +169,9 @@ class Util extends null {
169
169
  seasonId
170
170
  };
171
171
  }
172
- const [yearStr, monthStr] = seasonId.split('-');
173
- const targetYear = parseInt(yearStr, 10);
174
- const targetMonth = parseInt(monthStr, 10); // 1..12
172
+ const date = new Date(seasonId);
173
+ const targetYear = date.getUTCFullYear();
174
+ const targetMonth = date.getUTCMonth() + 1; // 1..12
175
175
  const referenceDate = new Date('2025-10-06T05:00:00.000Z');
176
176
  // Only handle the post-6 Oct seasons with 28-day intervals
177
177
  const refYear = referenceDate.getUTCFullYear();
@@ -195,6 +195,32 @@ class Util extends null {
195
195
  const endTime = new Date(startTime.getTime() + seasonDuration);
196
196
  return { startTime, endTime, seasonId };
197
197
  }
198
+ static getTournamentWindow(timestamp) {
199
+ const now = timestamp ?? new Date();
200
+ const day = now.getUTCDay(); // 0=Sun, 1=Mon, ..., 6=Sat
201
+ const hour = now.getUTCHours();
202
+ // Days since last Monday
203
+ let daysSinceMonday = (day + 6) % 7; // e.g., if Mon -> 0, Tue -> 1, etc.
204
+ // If today is Monday but before 5 AM, move back one full week
205
+ if (day === 1 && hour < 5) {
206
+ daysSinceMonday = 7;
207
+ }
208
+ // Last Monday 5:00 AM UTC
209
+ const lastMonday = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate() - daysSinceMonday, 5, 0, 0, 0));
210
+ // Next Monday 5:00 AM UTC (7 days after last Monday)
211
+ const nextMonday = new Date(Date.UTC(lastMonday.getUTCFullYear(), lastMonday.getUTCMonth(), lastMonday.getUTCDate() + 7, 5, 0, 0, 0));
212
+ const year = lastMonday.getUTCFullYear();
213
+ const month = String(lastMonday.getUTCMonth() + 1).padStart(2, '0');
214
+ const dayOfMonth = String(lastMonday.getUTCDate()).padStart(2, '0');
215
+ return {
216
+ id: `${year}-${month}-${dayOfMonth}`,
217
+ startTime: lastMonday,
218
+ endTime: nextMonday
219
+ };
220
+ }
221
+ static getTournamentWindowById(id) {
222
+ return this.getTournamentWindow(new Date(`${id}T05:00:00.000Z`));
223
+ }
198
224
  static async allSettled(values) {
199
225
  return (await Promise.allSettled(values))
200
226
  .filter((res) => res.status === 'fulfilled')
package/dist/util.spec.js CHANGED
@@ -86,7 +86,6 @@ describe('util', () => {
86
86
  });
87
87
  it('should pass Aug 2025 (seasonId)', async () => {
88
88
  const { endTime, startTime, seasonId } = Util_1.Util.getSeasonById('2025-08');
89
- console.log({ endTime, startTime, seasonId });
90
89
  const expectedStartTime = new Date('2025-07-28T05:00').toISOString();
91
90
  const expectedEndTime = new Date('2025-08-25T05:00').toISOString();
92
91
  expect(startTime.toISOString()).toBe(expectedStartTime);
@@ -95,7 +94,6 @@ describe('util', () => {
95
94
  });
96
95
  it('should pass March 2024 (seasonId)', async () => {
97
96
  const { endTime, startTime, seasonId } = Util_1.Util.getSeasonById('2024-03');
98
- console.log({ endTime, startTime, seasonId });
99
97
  const expectedEndTime = new Date('2024-03-25T05:00').toISOString();
100
98
  const expectedStartTime = new Date('2024-02-26T05:00').toISOString();
101
99
  expect(endTime.toISOString()).toBe(expectedEndTime);
@@ -104,7 +102,6 @@ describe('util', () => {
104
102
  });
105
103
  it('should pass Sep 2025 (seasonId)', async () => {
106
104
  const { endTime, startTime, seasonId } = Util_1.Util.getSeasonById('2025-09');
107
- console.log({ endTime, startTime, seasonId });
108
105
  const expectedStartTime = new Date('2025-08-25T05:00').toISOString();
109
106
  const expectedEndTime = new Date('2025-10-06T05:00').toISOString();
110
107
  expect(startTime.toISOString()).toBe(expectedStartTime);
@@ -113,7 +110,6 @@ describe('util', () => {
113
110
  });
114
111
  it('should pass October 2025 (seasonId)', async () => {
115
112
  const { endTime, startTime, seasonId } = Util_1.Util.getSeasonById('2025-10');
116
- console.log({ endTime, startTime, seasonId });
117
113
  const expectedStartTime = new Date('2025-10-06T05:00').toISOString();
118
114
  const expectedEndTime = new Date('2025-11-03T05:00').toISOString();
119
115
  expect(startTime.toISOString()).toBe(expectedStartTime);
@@ -122,7 +118,6 @@ describe('util', () => {
122
118
  });
123
119
  it('should pass Dec 2025 (seasonId)', async () => {
124
120
  const { endTime, startTime, seasonId } = Util_1.Util.getSeasonById('2025-12');
125
- console.log({ endTime, startTime, seasonId });
126
121
  const expectedStartTime = new Date('2025-12-01T05:00').toISOString();
127
122
  const expectedEndTime = new Date('2025-12-29T05:00').toISOString();
128
123
  expect(startTime.toISOString()).toBe(expectedStartTime);
@@ -131,7 +126,6 @@ describe('util', () => {
131
126
  });
132
127
  it('should pass Jan 2026 (seasonId)', async () => {
133
128
  const { endTime, startTime, seasonId } = Util_1.Util.getSeasonById('2026-01');
134
- console.log({ endTime, startTime, seasonId });
135
129
  const expectedStartTime = new Date('2025-12-29T05:00').toISOString();
136
130
  const expectedEndTime = new Date('2026-01-26T05:00').toISOString();
137
131
  expect(startTime.toISOString()).toBe(expectedStartTime);
@@ -140,11 +134,74 @@ describe('util', () => {
140
134
  });
141
135
  it('should pass Feb 2026 (seasonId)', async () => {
142
136
  const { endTime, startTime, seasonId } = Util_1.Util.getSeasonById('2026-02');
143
- console.log({ endTime, startTime, seasonId });
144
137
  const expectedStartTime = new Date('2026-01-26T05:00').toISOString();
145
138
  const expectedEndTime = new Date('2026-02-23T05:00').toISOString();
146
139
  expect(startTime.toISOString()).toBe(expectedStartTime);
147
140
  expect(endTime.toISOString()).toBe(expectedEndTime);
148
141
  expect(seasonId).toBe('2026-02');
149
142
  });
143
+ // tournament window
144
+ it('should get the correct tournament window for a Wednesday', async () => {
145
+ const timestamp = new Date('2024-03-20T10:00'); // Wednesday
146
+ const { endTime, startTime } = Util_1.Util.getTournamentWindow(timestamp);
147
+ const expectedStartTime = new Date('2024-03-18T05:00').toISOString(); // Last Monday 5 AM UTC
148
+ const expectedEndTime = new Date('2024-03-25T05:00').toISOString(); // Next Monday 5 AM UTC
149
+ expect(startTime.toISOString()).toBe(expectedStartTime);
150
+ expect(endTime.toISOString()).toBe(expectedEndTime);
151
+ });
152
+ it('should get the correct tournament window for a Monday after 5 AM', async () => {
153
+ const timestamp = new Date('2024-03-18T10:00'); // Monday after 5 AM
154
+ const { endTime, startTime } = Util_1.Util.getTournamentWindow(timestamp);
155
+ const expectedStartTime = new Date('2024-03-18T05:00').toISOString(); // Last Monday 5 AM UTC
156
+ const expectedEndTime = new Date('2024-03-25T05:00').toISOString(); // Next Monday 5 AM UTC
157
+ expect(startTime.toISOString()).toBe(expectedStartTime);
158
+ expect(endTime.toISOString()).toBe(expectedEndTime);
159
+ });
160
+ it('should get the correct tournament window for a Monday before 5 AM', async () => {
161
+ const timestamp = new Date('2024-03-18T04:00'); // Monday before 5 AM
162
+ const { endTime, startTime } = Util_1.Util.getTournamentWindow(timestamp);
163
+ const expectedStartTime = new Date('2024-03-11T05:00').toISOString(); // Last Monday 5 AM UTC (a week earlier)
164
+ const expectedEndTime = new Date('2024-03-18T05:00').toISOString(); // Next Monday 5 AM UTC
165
+ expect(startTime.toISOString()).toBe(expectedStartTime);
166
+ expect(endTime.toISOString()).toBe(expectedEndTime);
167
+ });
168
+ it('should get the correct tournament window for a Sunday', async () => {
169
+ const timestamp = new Date('2024-03-17T10:00'); // Sunday
170
+ const { endTime, startTime } = Util_1.Util.getTournamentWindow(timestamp);
171
+ const expectedStartTime = new Date('2024-03-11T05:00').toISOString(); // Last Monday 5 AM UTC
172
+ const expectedEndTime = new Date('2024-03-18T05:00').toISOString(); // Next Monday 5 AM UTC
173
+ expect(startTime.toISOString()).toBe(expectedStartTime);
174
+ expect(endTime.toISOString()).toBe(expectedEndTime);
175
+ });
176
+ it('should pass 5am Monday', async () => {
177
+ const timestamp = new Date('2025-10-06T05:00');
178
+ const { endTime, startTime } = Util_1.Util.getTournamentWindow(timestamp);
179
+ const expectedStartTime = new Date('2025-10-06T05:00').toISOString(); // Last Monday 5 AM UTC
180
+ const expectedEndTime = new Date('2025-10-13T05:00').toISOString(); // Next Monday 5 AM UTC
181
+ expect(startTime.toISOString()).toBe(expectedStartTime);
182
+ expect(endTime.toISOString()).toBe(expectedEndTime);
183
+ });
184
+ it('should pass 4:59am Monday', async () => {
185
+ const timestamp = new Date('2025-10-06T04:59');
186
+ const { endTime, startTime } = Util_1.Util.getTournamentWindow(timestamp);
187
+ const expectedStartTime = new Date('2025-09-29T05:00').toISOString();
188
+ const expectedEndTime = new Date('2025-10-06T05:00').toISOString();
189
+ expect(startTime.toISOString()).toBe(expectedStartTime);
190
+ expect(endTime.toISOString()).toBe(expectedEndTime);
191
+ });
192
+ it('should pass End of year', async () => {
193
+ const timestamp = new Date('2025-12-30T05:00');
194
+ const { endTime, startTime } = Util_1.Util.getTournamentWindow(timestamp);
195
+ const expectedStartTime = new Date('2025-12-29T05:00').toISOString();
196
+ const expectedEndTime = new Date('2026-01-05T05:00').toISOString();
197
+ expect(startTime.toISOString()).toBe(expectedStartTime);
198
+ expect(endTime.toISOString()).toBe(expectedEndTime);
199
+ });
200
+ it('should pass End of year (ID)', async () => {
201
+ const { endTime, startTime } = Util_1.Util.getTournamentWindowById('2025-12-30');
202
+ const expectedStartTime = new Date('2025-12-29T05:00').toISOString();
203
+ const expectedEndTime = new Date('2026-01-05T05:00').toISOString();
204
+ expect(startTime.toISOString()).toBe(expectedStartTime);
205
+ expect(endTime.toISOString()).toBe(expectedEndTime);
206
+ });
150
207
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clashofclans.js",
3
- "version": "3.5.2-dev.50a7e99",
3
+ "version": "3.5.4-dev.074d698",
4
4
  "description": "JavaScript library for interacting with the Clash of Clans API",
5
5
  "author": "https://clashofclans.js.org",
6
6
  "license": "MIT",