fix(GuildScheduledEvent): handle null recurrence_rule

#10543 djs
This commit is contained in:
Elysia
2025-01-21 01:15:13 +07:00
parent 8b05852a85
commit d0aa9b3702
6 changed files with 117 additions and 33 deletions

View File

@@ -53,11 +53,11 @@
"dependencies": { "dependencies": {
"@discordjs/builders": "^1.6.3", "@discordjs/builders": "^1.6.3",
"@discordjs/collection": "^1.5.3", "@discordjs/collection": "^1.5.3",
"@sapphire/async-queue": "^1.5.3", "@sapphire/async-queue": "^1.5.5",
"@sapphire/shapeshift": "^3.9.5", "@sapphire/shapeshift": "^3.9.5",
"discord-api-types": "^0.37.103", "discord-api-types": "^0.37.117",
"fetch-cookie": "^2.1.0", "fetch-cookie": "^2.1.0",
"find-process": "^1.4.7", "find-process": "^1.4.10",
"prism-media": "^1.3.5", "prism-media": "^1.3.5",
"qrcode": "^1.5.4", "qrcode": "^1.5.4",
"tough-cookie": "^4.1.4", "tough-cookie": "^4.1.4",

54
pnpm-lock.yaml generated
View File

@@ -15,20 +15,20 @@ importers:
specifier: ^1.5.3 specifier: ^1.5.3
version: 1.5.3 version: 1.5.3
'@sapphire/async-queue': '@sapphire/async-queue':
specifier: ^1.5.3 specifier: ^1.5.5
version: 1.5.3 version: 1.5.5
'@sapphire/shapeshift': '@sapphire/shapeshift':
specifier: ^3.9.5 specifier: ^3.9.5
version: 3.9.7 version: 3.9.7
discord-api-types: discord-api-types:
specifier: ^0.37.103 specifier: ^0.37.117
version: 0.37.103 version: 0.37.117
fetch-cookie: fetch-cookie:
specifier: ^2.1.0 specifier: ^2.1.0
version: 2.2.0 version: 2.2.0
find-process: find-process:
specifier: ^1.4.7 specifier: ^1.4.10
version: 1.4.7 version: 1.4.10
prism-media: prism-media:
specifier: ^1.3.5 specifier: ^1.3.5
version: 1.3.5 version: 1.3.5
@@ -552,8 +552,8 @@ packages:
'@qiwi/npm-registry-client@8.9.1': '@qiwi/npm-registry-client@8.9.1':
resolution: {integrity: sha512-rZF+mG+NfijR0SHphhTLHRr4aM4gtfdwoAMY6we2VGQam8vkN1cxGG1Lg/Llrj8Dd0Mu6VjdFQRyMMRZxtZR2A==} resolution: {integrity: sha512-rZF+mG+NfijR0SHphhTLHRr4aM4gtfdwoAMY6we2VGQam8vkN1cxGG1Lg/Llrj8Dd0Mu6VjdFQRyMMRZxtZR2A==}
'@sapphire/async-queue@1.5.3': '@sapphire/async-queue@1.5.5':
resolution: {integrity: sha512-x7zadcfJGxFka1Q3f8gCts1F0xMwCKbZweM85xECGI0hBTeIZJGGCrHgLggihBoprlQ/hBmDR5LKfIPqnmHM3w==} resolution: {integrity: sha512-cvGzxbba6sav2zZkH8GPf2oGk9yYoD5qrNWdu9fRehifgnFZJMV+nuy2nON2roRO4yQQ+v7MK/Pktl/HgfsUXg==}
engines: {node: '>=v14.0.0', npm: '>=7.0.0'} engines: {node: '>=v14.0.0', npm: '>=7.0.0'}
'@sapphire/fetch@2.4.2': '@sapphire/fetch@2.4.2':
@@ -1090,13 +1090,13 @@ packages:
resolution: {integrity: sha512-MxS8Ad995KpdAC0Jopo/ovGIroV/m0KHwzKfXxKag6FHOkGsH8/lv5yjgablcRxCJJC0oJeUMuO/gmaq+Wq46g==} resolution: {integrity: sha512-MxS8Ad995KpdAC0Jopo/ovGIroV/m0KHwzKfXxKag6FHOkGsH8/lv5yjgablcRxCJJC0oJeUMuO/gmaq+Wq46g==}
engines: {node: '>=4.0.0'} engines: {node: '>=4.0.0'}
commander@12.1.0:
resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==}
engines: {node: '>=18'}
commander@2.20.3: commander@2.20.3:
resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==}
commander@5.1.0:
resolution: {integrity: sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==}
engines: {node: '>= 6'}
commander@9.5.0: commander@9.5.0:
resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==} resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==}
engines: {node: ^12.20.0 || >=14} engines: {node: ^12.20.0 || >=14}
@@ -1330,8 +1330,8 @@ packages:
resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==}
engines: {node: '>=8'} engines: {node: '>=8'}
discord-api-types@0.37.103: discord-api-types@0.37.117:
resolution: {integrity: sha512-r+qitxXKe2l6KFw5odPdZSSqdEou+7eNC7BfbZ7mny5Me/K06wCTeKUMVeH/YsI9+4QQudskeQ307kr/7ppQ1A==} resolution: {integrity: sha512-d+Z6RKd7v3q22lsil7yASucqMfVVV0s0XSqu3cw7kyHVXiDO/mAnqMzqma26IYnIm2mk3TlupYJDGrdL908ZKA==}
discord-api-types@0.37.83: discord-api-types@0.37.83:
resolution: {integrity: sha512-urGGYeWtWNYMKnYlZnOnDHm8fVRffQs3U0SpE8RHeiuLKb/u92APS8HoQnPTFbnXmY1vVnXjXO4dOxcAn3J+DA==} resolution: {integrity: sha512-urGGYeWtWNYMKnYlZnOnDHm8fVRffQs3U0SpE8RHeiuLKb/u92APS8HoQnPTFbnXmY1vVnXjXO4dOxcAn3J+DA==}
@@ -1637,8 +1637,8 @@ packages:
resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
engines: {node: '>=8'} engines: {node: '>=8'}
find-process@1.4.7: find-process@1.4.10:
resolution: {integrity: sha512-/U4CYp1214Xrp3u3Fqr9yNynUrr5Le4y0SsJh2lMDDSbpwYSz3M2SMWQC+wqcx79cN8PQtHQIL8KnuY9M66fdg==} resolution: {integrity: sha512-ncYFnWEIwL7PzmrK1yZtaccN8GhethD37RzBHG6iOZoFYB4vSmLLXfeWJjeN5nMvCJMjOtBvBBF8OgxEcikiZg==}
hasBin: true hasBin: true
find-replace@3.0.0: find-replace@3.0.0:
@@ -2485,6 +2485,10 @@ packages:
resolution: {integrity: sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==} resolution: {integrity: sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==}
engines: {node: '>=10'} engines: {node: '>=10'}
loglevel@1.9.2:
resolution: {integrity: sha512-HgMmCqIJSAKqo68l0rS2AanEWfkxaZ5wNiEFb5ggm08lDs9Xl2KxBlX3PTcaD2chBM1gXAYf491/M2Rv8Jwayg==}
engines: {node: '>= 0.6.0'}
lru-cache@10.4.3: lru-cache@10.4.3:
resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==}
@@ -4574,7 +4578,7 @@ snapshots:
optionalDependencies: optionalDependencies:
npmlog: 4.1.2 npmlog: 4.1.2
'@sapphire/async-queue@1.5.3': {} '@sapphire/async-queue@1.5.5': {}
'@sapphire/fetch@2.4.2(encoding@0.1.13)': '@sapphire/fetch@2.4.2(encoding@0.1.13)':
dependencies: dependencies:
@@ -5162,9 +5166,9 @@ snapshots:
table-layout: 0.4.5 table-layout: 0.4.5
typical: 2.6.1 typical: 2.6.1
commander@2.20.3: {} commander@12.1.0: {}
commander@5.1.0: {} commander@2.20.3: {}
commander@9.5.0: {} commander@9.5.0: {}
@@ -5430,7 +5434,7 @@ snapshots:
dependencies: dependencies:
path-type: 4.0.0 path-type: 4.0.0
discord-api-types@0.37.103: {} discord-api-types@0.37.117: {}
discord-api-types@0.37.83: {} discord-api-types@0.37.83: {}
@@ -5885,13 +5889,11 @@ snapshots:
dependencies: dependencies:
to-regex-range: 5.0.1 to-regex-range: 5.0.1
find-process@1.4.7: find-process@1.4.10:
dependencies: dependencies:
chalk: 4.1.2 chalk: 4.1.2
commander: 5.1.0 commander: 12.1.0
debug: 4.3.5(supports-color@9.4.0) loglevel: 1.9.2
transitivePeerDependencies:
- supports-color
find-replace@3.0.0: find-replace@3.0.0:
dependencies: dependencies:
@@ -6970,6 +6972,8 @@ snapshots:
slice-ansi: 4.0.0 slice-ansi: 4.0.0
wrap-ansi: 6.2.0 wrap-ansi: 6.2.0
loglevel@1.9.2: {}
lru-cache@10.4.3: {} lru-cache@10.4.3: {}
lru-cache@5.1.1: lru-cache@5.1.1:

View File

@@ -4,7 +4,7 @@ const EventEmitter = require('node:events');
const { setImmediate } = require('node:timers'); const { setImmediate } = require('node:timers');
const { setTimeout: sleep } = require('node:timers/promises'); const { setTimeout: sleep } = require('node:timers/promises');
const { Collection } = require('@discordjs/collection'); const { Collection } = require('@discordjs/collection');
const { RPCErrorCodes } = require('discord-api-types/v9'); const { RPCErrorCodes } = require('discord-api-types/v10');
const WebSocketShard = require('./WebSocketShard'); const WebSocketShard = require('./WebSocketShard');
const PacketHandlers = require('./handlers'); const PacketHandlers = require('./handlers');
const { Error } = require('../../errors'); const { Error } = require('../../errors');

View File

@@ -194,6 +194,55 @@ class GuildScheduledEvent extends Base {
} else { } else {
this.image ??= null; this.image ??= null;
} }
/**
* Represents the recurrence rule for a {@link GuildScheduledEvent}.
* @typedef {Object} GuildScheduledEventRecurrenceRule
* @property {number} startTimestamp The timestamp the recurrence rule interval starts at
* @property {Date} startAt The time the recurrence rule interval starts at
* @property {?number} endTimestamp The timestamp the recurrence rule interval ends at
* @property {?Date} endAt The time the recurrence rule interval ends at
* @property {GuildScheduledEventRecurrenceRuleFrequency} frequency How often the event occurs
* @property {number} interval The spacing between the events
* @property {?GuildScheduledEventRecurrenceRuleWeekday[]} byWeekday The days within a week to recur on
* @property {?GuildScheduledEventRecurrenceRuleNWeekday[]} byNWeekday The days within a week to recur on
* @property {?GuildScheduledEventRecurrenceRuleMonth[]} byMonth The months to recur on
* @property {?number[]} byMonthDay The days within a month to recur on
* @property {?number[]} byYearDay The days within a year to recur on
* @property {?number} count The total amount of times the event is allowed to recur before stopping
*/
/**
* @typedef {Object} GuildScheduledEventRecurrenceRuleNWeekday
* @property {number} n The week to recur on
* @property {GuildScheduledEventRecurrenceRuleWeekday} day The day within the week to recur on
*/
if ('recurrence_rule' in data) {
/**
* The recurrence rule for this scheduled event
* @type {?GuildScheduledEventRecurrenceRule}
*/
this.recurrenceRule = data.recurrence_rule && {
startTimestamp: Date.parse(data.recurrence_rule.start),
get startAt() {
return new Date(this.startTimestamp);
},
endTimestamp: data.recurrence_rule.end && Date.parse(data.recurrence_rule.end),
get endAt() {
return this.endTimestamp && new Date(this.endTimestamp);
},
frequency: data.recurrence_rule.frequency,
interval: data.recurrence_rule.interval,
byWeekday: data.recurrence_rule.by_weekday,
byNWeekday: data.recurrence_rule.by_n_weekday,
byMonth: data.recurrence_rule.by_month,
byMonthDay: data.recurrence_rule.by_month_day,
byYearDay: data.recurrence_rule.by_year_day,
count: data.recurrence_rule.count,
};
} else {
this.recurrenceRule ??= null;
}
} }
/** /**

37
typings/index.d.ts vendored
View File

@@ -57,7 +57,11 @@ import {
TeamMemberRole, TeamMemberRole,
APIPoll, APIPoll,
APIPollAnswer, APIPollAnswer,
} from 'discord-api-types/v9'; GuildScheduledEventRecurrenceRuleWeekday,
GuildScheduledEventRecurrenceRuleMonth,
GuildScheduledEventRecurrenceRuleFrequency,
APIChatInputApplicationCommandInteractionData, APIContextMenuInteractionData
} from 'discord-api-types/v10';
import { ChildProcess, ChildProcessWithoutNullStreams } from 'node:child_process'; import { ChildProcess, ChildProcessWithoutNullStreams } from 'node:child_process';
import { EventEmitter } from 'node:events'; import { EventEmitter } from 'node:events';
import { AgentOptions } from 'node:https'; import { AgentOptions } from 'node:https';
@@ -553,10 +557,16 @@ export abstract class BaseCommandInteraction<Cached extends CacheType = CacheTyp
public showModal(modal: Modal | ModalOptions): Promise<void>; public showModal(modal: Modal | ModalOptions): Promise<void>;
private transformOption( private transformOption(
option: APIApplicationCommandOption, option: APIApplicationCommandOption,
resolved: APIApplicationCommandInteractionData['resolved'], resolved: Extract<
APIApplicationCommandInteractionData,
APIChatInputApplicationCommandInteractionData | APIContextMenuInteractionData
>['resolved'],
): CommandInteractionOption<Cached>; ): CommandInteractionOption<Cached>;
private transformResolved( private transformResolved(
resolved: APIApplicationCommandInteractionData['resolved'], resolved: Extract<
APIApplicationCommandInteractionData,
APIChatInputApplicationCommandInteractionData | APIContextMenuInteractionData
>['resolved'],
): CommandInteractionResolvedData<Cached>; ): CommandInteractionResolvedData<Cached>;
} }
@@ -1769,6 +1779,7 @@ export class GuildScheduledEvent<S extends GuildScheduledEventStatus = GuildSche
public entityMetadata: GuildScheduledEventEntityMetadata; public entityMetadata: GuildScheduledEventEntityMetadata;
public userCount: number | null; public userCount: number | null;
public creator: User | null; public creator: User | null;
public recurrenceRule: GuildScheduledEventRecurrenceRule | null;
public readonly createdTimestamp: number; public readonly createdTimestamp: number;
public readonly createdAt: Date; public readonly createdAt: Date;
public readonly scheduledStartAt: Date; public readonly scheduledStartAt: Date;
@@ -1804,6 +1815,26 @@ export class GuildScheduledEvent<S extends GuildScheduledEventStatus = GuildSche
public isScheduled(): this is GuildScheduledEvent<'SCHEDULED'>; public isScheduled(): this is GuildScheduledEvent<'SCHEDULED'>;
} }
export interface GuildScheduledEventRecurrenceRule {
startTimestamp: number;
get startAt(): Date;
endTimestamp: number | null;
get endAt(): Date | null;
frequency: GuildScheduledEventRecurrenceRuleFrequency;
interval: number;
byWeekday: readonly GuildScheduledEventRecurrenceRuleWeekday[] | null;
byNWeekday: readonly GuildScheduledEventRecurrenceRuleNWeekday[] | null;
byMonth: readonly GuildScheduledEventRecurrenceRuleMonth[] | null;
byMonthDay: readonly number[] | null;
byYearDay: readonly number[] | null;
count: number | null;
}
export interface GuildScheduledEventRecurrenceRuleNWeekday {
n: number;
day: GuildScheduledEventRecurrenceRuleWeekday;
}
export class GuildTemplate extends Base { export class GuildTemplate extends Base {
private constructor(client: Client, data: RawGuildTemplateData); private constructor(client: Client, data: RawGuildTemplateData);
public readonly createdTimestamp: number; public readonly createdTimestamp: number;

View File

@@ -87,7 +87,7 @@ import {
GuildVerificationLevel, GuildVerificationLevel,
GuildFeature, GuildFeature,
LocalizationMap, LocalizationMap,
} from 'discord-api-types/v9'; } from 'discord-api-types/v10';
import { GuildChannel, Guild, PermissionOverwrites } from '.'; import { GuildChannel, Guild, PermissionOverwrites } from '.';
import type { import type {
AutoModerationActionTypes, AutoModerationActionTypes,