From 13b8a32d42edf0f20a0b5d847f8f327de5db3fdd Mon Sep 17 00:00:00 2001 From: MARCROCK22 <57925328+MARCROCK22@users.noreply.github.com> Date: Fri, 27 Sep 2024 23:08:50 -0400 Subject: [PATCH] fix rest types, collectors update, improve types (#266) * feat: ctx types, delete threads cache, cache.channels.threads, changes to collectors, fix rest types * fix: use apithreadchannel instead * feat: revert threads relationship, fix collectors * fix: cache thread when creating * fix: unused * feat: entitlement trasnformer * fix: non-null assertion * fix: circular? * fix: collector onStop reason type * fix: types * feat: onPass method * fix: undefined value --- biome.json | 2 +- package.json | 4 +- pnpm-lock.yaml | 100 +++++----- src/api/Routes/applications.ts | 77 +++----- src/api/Routes/channels.ts | 118 +++++------ src/api/Routes/gateway.ts | 7 +- src/api/Routes/guilds.ts | 197 ++++++++----------- src/api/Routes/index.ts | 23 +-- src/api/Routes/interactions.ts | 14 +- src/api/Routes/invites.ts | 7 +- src/api/Routes/skus.ts | 9 +- src/api/Routes/stage-instances.ts | 15 +- src/api/Routes/stickers.ts | 7 +- src/api/Routes/users.ts | 31 ++- src/api/Routes/voice.ts | 5 +- src/api/Routes/webhooks.ts | 45 ++--- src/api/api.ts | 61 +++--- src/builders/Attachment.ts | 2 +- src/builders/types.ts | 6 +- src/cache/adapters/limited.ts | 3 - src/cache/index.ts | 14 +- src/cache/resources/default/guild-related.ts | 3 +- src/cache/resources/guilds.ts | 21 +- src/cache/resources/messages.ts | 6 +- src/cache/resources/threads.ts | 44 ----- src/client/base.ts | 15 +- src/client/transformers.ts | 5 + src/commands/applications/chatcontext.ts | 54 +++-- src/commands/applications/entrycontext.ts | 18 +- src/commands/applications/menucontext.ts | 18 +- src/common/it/utils.ts | 6 +- src/common/shorters/application.ts | 6 +- src/common/shorters/bans.ts | 4 +- src/common/shorters/channels.ts | 6 +- src/common/shorters/guilds.ts | 7 +- src/common/shorters/interaction.ts | 11 +- src/common/shorters/members.ts | 21 +- src/common/shorters/messages.ts | 2 +- src/common/shorters/templates.ts | 2 +- src/common/shorters/threads.ts | 32 ++- src/common/shorters/webhook.ts | 2 +- src/components/handler.ts | 50 +++-- src/events/handler.ts | 93 ++++++--- src/events/hooks/entitlement.ts | 8 +- src/events/hooks/guild.ts | 4 +- src/events/hooks/integration.ts | 4 +- src/events/hooks/thread.ts | 2 +- src/events/hooks/typing.ts | 2 +- src/index.ts | 4 +- src/structures/GuildMember.ts | 3 +- src/structures/Interaction.ts | 66 ++++--- src/structures/Message.ts | 4 +- src/structures/extra/BaseGuild.ts | 4 +- src/types/gateway.ts | 2 +- src/types/payloads/channel.ts | 2 +- src/websocket/discord/shard.ts | 4 +- src/websocket/discord/workermanager.ts | 6 +- tsconfig.json | 4 +- 58 files changed, 610 insertions(+), 682 deletions(-) delete mode 100644 src/cache/resources/threads.ts diff --git a/biome.json b/biome.json index 11a1f4e..f1a5baa 100644 --- a/biome.json +++ b/biome.json @@ -1,5 +1,5 @@ { - "$schema": "https://biomejs.dev/schemas/1.9.0/schema.json", + "$schema": "https://biomejs.dev/schemas/1.9.2/schema.json", "vcs": { "enabled": true, "clientKind": "git", diff --git a/package.json b/package.json index c599116..71ddc9c 100644 --- a/package.json +++ b/package.json @@ -20,10 +20,10 @@ "author": "MARCROCK22", "license": "MIT", "devDependencies": { - "@biomejs/biome": "1.9.1", + "@biomejs/biome": "1.9.2", "@commitlint/cli": "^19.5.0", "@commitlint/config-conventional": "^19.5.0", - "@types/node": "^22.5.5", + "@types/node": "^22.6.1", "husky": "^9.1.6", "lint-staged": "^15.2.10", "typescript": "^5.6.2" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 361835b..a46d056 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,17 +9,17 @@ importers: .: devDependencies: '@biomejs/biome': - specifier: 1.9.1 - version: 1.9.1 + specifier: 1.9.2 + version: 1.9.2 '@commitlint/cli': specifier: ^19.5.0 - version: 19.5.0(@types/node@22.5.5)(typescript@5.6.2) + version: 19.5.0(@types/node@22.6.1)(typescript@5.6.2) '@commitlint/config-conventional': specifier: ^19.5.0 version: 19.5.0 '@types/node': - specifier: ^22.5.5 - version: 22.5.5 + specifier: ^22.6.1 + version: 22.6.1 husky: specifier: ^9.1.6 version: 9.1.6 @@ -44,55 +44,55 @@ packages: resolution: {integrity: sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==} engines: {node: '>=6.9.0'} - '@biomejs/biome@1.9.1': - resolution: {integrity: sha512-Ps0Rg0zg3B1zpx+zQHMz5b0n0PBNCAaXttHEDTVrJD5YXR6Uj3T+abTDgeS3wsu4z5i2whqcE1lZxGyWH4bZYg==} + '@biomejs/biome@1.9.2': + resolution: {integrity: sha512-4j2Gfwft8Jqp1X0qLYvK4TEy4xhTo4o6rlvJPsjPeEame8gsmbGQfOPBkw7ur+7/Z/f0HZmCZKqbMvR7vTXQYQ==} engines: {node: '>=14.21.3'} hasBin: true - '@biomejs/cli-darwin-arm64@1.9.1': - resolution: {integrity: sha512-js0brHswq/BoeKgfSEUJYOjUOlML6p65Nantti+PsoQ61u9+YVGIZ7325LK7iUpDH8KVJT+Bx7K2b/6Q//W1Pw==} + '@biomejs/cli-darwin-arm64@1.9.2': + resolution: {integrity: sha512-rbs9uJHFmhqB3Td0Ro+1wmeZOHhAPTL3WHr8NtaVczUmDhXkRDWScaxicG9+vhSLj1iLrW47itiK6xiIJy6vaA==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [darwin] - '@biomejs/cli-darwin-x64@1.9.1': - resolution: {integrity: sha512-2zVyjUg5rN0k8XrytkubQWLbp2r/AS5wPhXs4vgVjvqbLnzo32EGX8p61gzroF2dH9DCUCfskdrigCGqNdEbpg==} + '@biomejs/cli-darwin-x64@1.9.2': + resolution: {integrity: sha512-BlfULKijNaMigQ9GH9fqJVt+3JTDOSiZeWOQtG/1S1sa8Lp046JHG3wRJVOvekTPL9q/CNFW1NVG8J0JN+L1OA==} engines: {node: '>=14.21.3'} cpu: [x64] os: [darwin] - '@biomejs/cli-linux-arm64-musl@1.9.1': - resolution: {integrity: sha512-L/JmXKvhsZ1lTgqOr3tWkzuY/NRppdIscHeC9aaiR72WjnBgJS94mawl9BWmGB3aWBc0q6oSDWnBS7617EMMmA==} + '@biomejs/cli-linux-arm64-musl@1.9.2': + resolution: {integrity: sha512-ZATvbUWhNxegSALUnCKWqetTZqrK72r2RsFD19OK5jXDj/7o1hzI1KzDNG78LloZxftrwr3uI9SqCLh06shSZw==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [linux] - '@biomejs/cli-linux-arm64@1.9.1': - resolution: {integrity: sha512-QgxwfnG+r2aer5RNGR67Ey91Tv7xXW8E9YckHhwuyWjdLEvKWkrSJrhVG/6ub0kVvTSNkYOuT/7/jMOFBuUbRA==} + '@biomejs/cli-linux-arm64@1.9.2': + resolution: {integrity: sha512-T8TJuSxuBDeQCQzxZu2o3OU4eyLumTofhCxxFd3+aH2AEWVMnH7Z/c3QP1lHI5RRMBP9xIJeMORqDQ5j+gVZzw==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [linux] - '@biomejs/cli-linux-x64-musl@1.9.1': - resolution: {integrity: sha512-gY+eFLIAW45v3WicQHicvjRfA0ntMZHx7h937bXwBMFNFoKmB6rMi6+fKQ6/hiS6juhsFxZdZIz20m15s49J6A==} + '@biomejs/cli-linux-x64-musl@1.9.2': + resolution: {integrity: sha512-CjPM6jT1miV5pry9C7qv8YJk0FIZvZd86QRD3atvDgfgeh9WQU0k2Aoo0xUcPdTnoz0WNwRtDicHxwik63MmSg==} engines: {node: '>=14.21.3'} cpu: [x64] os: [linux] - '@biomejs/cli-linux-x64@1.9.1': - resolution: {integrity: sha512-F0INygtzI2L2n2R1KtYHGr3YWDt9Up1zrUluwembM+iJ1dXN3qzlSb7deFUsSJm4FaIPriqs6Xa56ukdQW6UeQ==} + '@biomejs/cli-linux-x64@1.9.2': + resolution: {integrity: sha512-T0cPk3C3Jr2pVlsuQVTBqk2qPjTm8cYcTD9p/wmR9MeVqui1C/xTVfOIwd3miRODFMrJaVQ8MYSXnVIhV9jTjg==} engines: {node: '>=14.21.3'} cpu: [x64] os: [linux] - '@biomejs/cli-win32-arm64@1.9.1': - resolution: {integrity: sha512-7Jahxar3OB+aTPOgXisMJmMKMsjcK+UmdlG3UIOQjzN/ZFEsPV+GT3bfrVjZDQaCw/zes0Cqd7VTWFjFTC/+MQ==} + '@biomejs/cli-win32-arm64@1.9.2': + resolution: {integrity: sha512-2x7gSty75bNIeD23ZRPXyox6Z/V0M71ObeJtvQBhi1fgrvPdtkEuw7/0wEHg6buNCubzOFuN9WYJm6FKoUHfhg==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [win32] - '@biomejs/cli-win32-x64@1.9.1': - resolution: {integrity: sha512-liSRWjWzFhyG7s1jg/Bbv9FL+ha/CEd5tFO3+dFIJNplL4TnvAivtyfRVi/tu/pNjISbV1k9JwdBewtAKAgA0w==} + '@biomejs/cli-win32-x64@1.9.2': + resolution: {integrity: sha512-JC3XvdYcjmu1FmAehVwVV0SebLpeNTnO2ZaMdGCSOdS7f8O9Fq14T2P1gTG1Q29Q8Dt1S03hh0IdVpIZykOL8g==} engines: {node: '>=14.21.3'} cpu: [x64] os: [win32] @@ -169,8 +169,8 @@ packages: '@types/conventional-commits-parser@5.0.0': resolution: {integrity: sha512-loB369iXNmAZglwWATL+WRe+CRMmmBPtpolYzIebFaX4YA3x+BEfLqhUAV9WanycKI3TG1IMr5bMJDajDKLlUQ==} - '@types/node@22.5.5': - resolution: {integrity: sha512-Xjs4y5UPO/CLdzpgR6GirZJx36yScjh73+2NlLlkFRSoQN8B0DpfXPdZGnvVmLRLOsqDpOfTNv7D9trgGhmOIA==} + '@types/node@22.6.1': + resolution: {integrity: sha512-V48tCfcKb/e6cVUigLAaJDAILdMP0fUW6BidkPK4GpGjXcfbnoHasCZDwz3N3yVt5we2RHm4XTQCpv0KJz9zqw==} JSONStream@1.3.5: resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} @@ -741,46 +741,46 @@ snapshots: js-tokens: 4.0.0 picocolors: 1.1.0 - '@biomejs/biome@1.9.1': + '@biomejs/biome@1.9.2': optionalDependencies: - '@biomejs/cli-darwin-arm64': 1.9.1 - '@biomejs/cli-darwin-x64': 1.9.1 - '@biomejs/cli-linux-arm64': 1.9.1 - '@biomejs/cli-linux-arm64-musl': 1.9.1 - '@biomejs/cli-linux-x64': 1.9.1 - '@biomejs/cli-linux-x64-musl': 1.9.1 - '@biomejs/cli-win32-arm64': 1.9.1 - '@biomejs/cli-win32-x64': 1.9.1 + '@biomejs/cli-darwin-arm64': 1.9.2 + '@biomejs/cli-darwin-x64': 1.9.2 + '@biomejs/cli-linux-arm64': 1.9.2 + '@biomejs/cli-linux-arm64-musl': 1.9.2 + '@biomejs/cli-linux-x64': 1.9.2 + '@biomejs/cli-linux-x64-musl': 1.9.2 + '@biomejs/cli-win32-arm64': 1.9.2 + '@biomejs/cli-win32-x64': 1.9.2 - '@biomejs/cli-darwin-arm64@1.9.1': + '@biomejs/cli-darwin-arm64@1.9.2': optional: true - '@biomejs/cli-darwin-x64@1.9.1': + '@biomejs/cli-darwin-x64@1.9.2': optional: true - '@biomejs/cli-linux-arm64-musl@1.9.1': + '@biomejs/cli-linux-arm64-musl@1.9.2': optional: true - '@biomejs/cli-linux-arm64@1.9.1': + '@biomejs/cli-linux-arm64@1.9.2': optional: true - '@biomejs/cli-linux-x64-musl@1.9.1': + '@biomejs/cli-linux-x64-musl@1.9.2': optional: true - '@biomejs/cli-linux-x64@1.9.1': + '@biomejs/cli-linux-x64@1.9.2': optional: true - '@biomejs/cli-win32-arm64@1.9.1': + '@biomejs/cli-win32-arm64@1.9.2': optional: true - '@biomejs/cli-win32-x64@1.9.1': + '@biomejs/cli-win32-x64@1.9.2': optional: true - '@commitlint/cli@19.5.0(@types/node@22.5.5)(typescript@5.6.2)': + '@commitlint/cli@19.5.0(@types/node@22.6.1)(typescript@5.6.2)': dependencies: '@commitlint/format': 19.5.0 '@commitlint/lint': 19.5.0 - '@commitlint/load': 19.5.0(@types/node@22.5.5)(typescript@5.6.2) + '@commitlint/load': 19.5.0(@types/node@22.6.1)(typescript@5.6.2) '@commitlint/read': 19.5.0 '@commitlint/types': 19.5.0 tinyexec: 0.3.0 @@ -827,7 +827,7 @@ snapshots: '@commitlint/rules': 19.5.0 '@commitlint/types': 19.5.0 - '@commitlint/load@19.5.0(@types/node@22.5.5)(typescript@5.6.2)': + '@commitlint/load@19.5.0(@types/node@22.6.1)(typescript@5.6.2)': dependencies: '@commitlint/config-validator': 19.5.0 '@commitlint/execute-rule': 19.5.0 @@ -835,7 +835,7 @@ snapshots: '@commitlint/types': 19.5.0 chalk: 5.3.0 cosmiconfig: 9.0.0(typescript@5.6.2) - cosmiconfig-typescript-loader: 5.0.0(@types/node@22.5.5)(cosmiconfig@9.0.0(typescript@5.6.2))(typescript@5.6.2) + cosmiconfig-typescript-loader: 5.0.0(@types/node@22.6.1)(cosmiconfig@9.0.0(typescript@5.6.2))(typescript@5.6.2) lodash.isplainobject: 4.0.6 lodash.merge: 4.6.2 lodash.uniq: 4.5.0 @@ -888,9 +888,9 @@ snapshots: '@types/conventional-commits-parser@5.0.0': dependencies: - '@types/node': 22.5.5 + '@types/node': 22.6.1 - '@types/node@22.5.5': + '@types/node@22.6.1': dependencies: undici-types: 6.19.8 @@ -993,9 +993,9 @@ snapshots: meow: 12.1.1 split2: 4.2.0 - cosmiconfig-typescript-loader@5.0.0(@types/node@22.5.5)(cosmiconfig@9.0.0(typescript@5.6.2))(typescript@5.6.2): + cosmiconfig-typescript-loader@5.0.0(@types/node@22.6.1)(cosmiconfig@9.0.0(typescript@5.6.2))(typescript@5.6.2): dependencies: - '@types/node': 22.5.5 + '@types/node': 22.6.1 cosmiconfig: 9.0.0(typescript@5.6.2) jiti: 1.21.6 typescript: 5.6.2 diff --git a/src/api/Routes/applications.ts b/src/api/Routes/applications.ts index f49f9e9..02a3afc 100644 --- a/src/api/Routes/applications.ts +++ b/src/api/Routes/applications.ts @@ -36,72 +36,60 @@ import type { RESTPutAPIApplicationRoleConnectionMetadataResult, RESTPutAPIGuildApplicationCommandsPermissionsResult, } from '../../types'; - -import type { ProxyRequestMethod } from '../Router'; -import type { RestArguments } from '../api'; +import type { RestArguments, RestArgumentsNoBody } from '../api'; export interface ApplicationRoutes { applications: (id: string) => { guilds: (id: string) => { commands: { get( - args?: RestArguments, + args?: RestArgumentsNoBody, ): Promise; post( - args: RestArguments, + args: RestArguments, ): Promise; put( - args?: RestArguments, + args?: RestArguments, ): Promise; permissions: { - get( - args?: RestArguments, - ): Promise; + get(args?: RestArgumentsNoBody): Promise; }; ( id: string, ): { - get(args?: RestArguments): Promise; + get(args?: RestArgumentsNoBody): Promise; patch( - args: RestArguments, + args: RestArguments, ): Promise; - delete(args?: RestArguments): Promise; + delete(args?: RestArgumentsNoBody): Promise; permissions: { - get( - args?: RestArguments, - ): Promise; + get(args?: RestArgumentsNoBody): Promise; put( - args?: RestArguments, + args?: RestArguments, ): Promise; }; }; }; }; commands: { - get( - args?: RestArguments, - ): Promise; - post( - args: RestArguments, - ): Promise; - put( - args?: RestArguments, - ): Promise; + get(args?: RestArgumentsNoBody): Promise; + post(args: RestArguments): Promise; + put(args?: RestArguments): Promise; ( id: string, ): { - get(args?: RestArguments): Promise; + get(args?: RestArgumentsNoBody): Promise; patch( - args: RestArguments, + args: RestArguments, ): Promise; - delete(args?: RestArguments): Promise; + delete(args?: RestArgumentsNoBody): Promise; }; }; 'role-connections': { metadata: { - get(args?: RestArguments): Promise; + get(args?: RestArgumentsNoBody): Promise; put( - args: RestArguments, + args: RestArguments, ): Promise; }; }; @@ -109,38 +97,29 @@ export interface ApplicationRoutes { ( id: string, ): { - get(args?: RestArguments): Promise; - patch( - args?: RestArguments, - ): Promise; - delete(args?: RestArguments): Promise; + get(args?: RestArgumentsNoBody): Promise; + patch(args?: RestArguments): Promise; + delete(args?: RestArgumentsNoBody): Promise; }; get( - args?: RestArguments>, + args?: RestArgumentsNoBody>, ): Promise; - post( - args?: RestArguments, - ): Promise; + post(args?: RestArguments): Promise; }; entitlements: { - get( - args?: RestArguments, - ): Promise; - post( - args: RestArguments, - ): Promise; - + get(args?: RestArgumentsNoBody): Promise; + post(args: RestArguments): Promise; ( id: string, ): { - delete(args?: RestArguments): Promise; + delete(args?: RestArgumentsNoBody): Promise; consume: { - post(args?: RestArguments): Promise; + post(args?: RestArgumentsNoBody): Promise; }; }; }; skus: { - get(args?: RestArguments): Promise; + get(args?: RestArgumentsNoBody): Promise; }; }; } diff --git a/src/api/Routes/channels.ts b/src/api/Routes/channels.ts index ef91b0b..ba0fea1 100644 --- a/src/api/Routes/channels.ts +++ b/src/api/Routes/channels.ts @@ -56,22 +56,19 @@ import type { RESTPutAPIChannelRecipientResult, RESTPutAPIChannelThreadMembersResult, } from '../../types'; -import type { ProxyRequestMethod } from '../Router'; -import type { RestArguments } from '../api'; +import type { RestArguments, RestArgumentsNoBody } from '../api'; export interface ChannelRoutes { channels(id: string): { - get(args?: RestArguments): Promise; - patch( - args: RestArguments, - ): Promise; - delete(args?: RestArguments): Promise; + get(args?: RestArgumentsNoBody): Promise; + patch(args: RestArguments): Promise; + delete(args?: RestArgumentsNoBody): Promise; users: (id: '@me') => { threads: { archived: { private: { get( - args?: RestArguments, + args?: RestArgumentsNoBody, ): Promise; }; }; @@ -79,154 +76,127 @@ export interface ChannelRoutes { }; 'thread-members': { get( - args?: RestArguments, + args?: RestArgumentsNoBody, ): Promise; ( id: '@me', ): { - put(args?: RestArguments): Promise; - delete(args?: RestArguments): Promise; + put(args?: RestArgumentsNoBody): Promise; + delete(args?: RestArgumentsNoBody): Promise; }; ( id: string, ): { get( - args?: RestArguments, + args?: RestArgumentsNoBody, ): Promise; - put(args?: RestArguments): Promise; - delete(args?: RestArguments): Promise; + put(args?: RestArgumentsNoBody): Promise; + delete(args?: RestArgumentsNoBody): Promise; }; }; threads: { post( - args: RestArguments< - ProxyRequestMethod.Post, - RESTPostAPIChannelThreadsJSONBody | RESTPostAPIGuildForumThreadsJSONBody - >, + args: RestArguments, ): Promise; archived: { public: { get( - args?: RestArguments, + args?: RestArgumentsNoBody, ): Promise; }; private: { get( - args?: RestArguments, + args?: RestArgumentsNoBody, ): Promise; }; }; }; recipients: (id: string) => { - put( - args?: RestArguments, - ): Promise; - delete(args?: RestArguments): Promise; + put(args?: RestArguments): Promise; + delete(args?: RestArgumentsNoBody): Promise; }; pins: { - get(args?: RestArguments): Promise; + get(args?: RestArgumentsNoBody): Promise; ( id: string, ): { - put(args?: RestArguments): Promise; - delete(args?: RestArguments): Promise; + put(args?: RestArgumentsNoBody): Promise; + delete(args?: RestArgumentsNoBody): Promise; }; }; followers: { - post( - args: RestArguments, - ): Promise; + post(args: RestArguments): Promise; }; permissions: (id: string) => { - put( - args?: RestArguments, - ): Promise; - delete(args?: RestArguments): Promise; + put(args?: RestArguments): Promise; + delete(args?: RestArgumentsNoBody): Promise; }; invites: { - get(args?: RestArguments): Promise; - post( - args: RestArguments, - ): Promise; + get(args?: RestArgumentsNoBody): Promise; + post(args: RestArguments): Promise; }; messages: { - get( - args?: RestArguments, - ): Promise; - post( - args: RestArguments, - ): Promise; + get(args?: RestArgumentsNoBody): Promise; + post(args: RestArguments): Promise; 'bulk-delete': { post( - args: RestArguments, + args: RestArguments, ): Promise; }; ( id: string, ): { - get(args?: RestArguments): Promise; - patch( - args: RestArguments, - ): Promise; - delete(args?: RestArguments): Promise; + get(args?: RestArgumentsNoBody): Promise; + patch(args: RestArguments): Promise; + delete(args?: RestArgumentsNoBody): Promise; threads: { post( - args: RestArguments, + args: RestArguments, ): Promise; }; crosspost: { - post(args: RestArguments): Promise; + post(args: RestArgumentsNoBody): Promise; }; reactions: { - delete( - args?: RestArguments, - ): Promise; + delete(args?: RestArgumentsNoBody): Promise; ( emoji: string, ): { get( - args?: RestArguments, + args?: RestArgumentsNoBody, ): Promise; - delete(args?: RestArguments): Promise; + delete(args?: RestArgumentsNoBody): Promise; ( id: '@me', ): { - put(args?: RestArguments): Promise; - delete( - args?: RestArguments, - ): Promise; + put(args?: RestArgumentsNoBody): Promise; + delete(args?: RestArgumentsNoBody): Promise; }; ( id: string, ): { - delete( - args?: RestArguments, - ): Promise; + delete(args?: RestArgumentsNoBody): Promise; }; }; }; }; }; typing: { - post(args?: RestArguments): Promise; + post(args?: RestArgumentsNoBody): Promise; }; webhooks: { - get(args?: RestArguments): Promise; - post( - args: RestArguments, - ): Promise; + get(args?: RestArgumentsNoBody): Promise; + post(args: RestArguments): Promise; }; 'voice-status': { - put(args: RestArguments): Promise; + put(args: RestArguments<{ status: string | null }>): Promise; }; polls(messageId: string): { answers(id: ValidAnswerId): { - get( - args?: RestArguments, - ): Promise; + get(args?: RestArgumentsNoBody): Promise; }; expire: { - post(args?: RestArguments): Promise; + post(args?: RestArgumentsNoBody): Promise; }; }; }; diff --git a/src/api/Routes/gateway.ts b/src/api/Routes/gateway.ts index 0b62502..bfcf479 100644 --- a/src/api/Routes/gateway.ts +++ b/src/api/Routes/gateway.ts @@ -1,12 +1,11 @@ import type { RESTGetAPIGatewayBotResult, RESTGetAPIGatewayResult } from '../../types'; -import type { ProxyRequestMethod } from '../Router'; -import type { RestArguments } from '../api'; +import type { RestArgumentsNoBody } from '../api'; export interface GatewayRoutes { gateway: { - get(args?: RestArguments): Promise; + get(args?: RestArgumentsNoBody): Promise; bot: { - get(args?: RestArguments): Promise; + get(args?: RestArgumentsNoBody): Promise; }; }; } diff --git a/src/api/Routes/guilds.ts b/src/api/Routes/guilds.ts index 2d882bb..0944cd8 100644 --- a/src/api/Routes/guilds.ts +++ b/src/api/Routes/guilds.ts @@ -117,274 +117,233 @@ import type { RESTPutAPIGuildMemberRoleResult, RESTPutAPIGuildTemplateSyncResult, } from '../../types'; -import type { ProxyRequestMethod } from '../Router'; -import type { RestArguments } from '../api'; +import type { RestArguments, RestArgumentsNoBody } from '../api'; import type { RawFile } from '../shared'; export interface GuildRoutes { guilds: { - post(args: RestArguments): Promise; + post(args: RestArguments): Promise; templates(code: string): { - get(args?: RestArguments): Promise; - post( - args: RestArguments, - ): Promise; + get(args?: RestArgumentsNoBody): Promise; + post(args: RestArguments): Promise; }; ( id: string, ): { - get(args?: RestArguments): Promise; - patch(args: RestArguments): Promise; - delete(args?: RestArguments): Promise; + get(args?: RestArgumentsNoBody): Promise; + patch(args: RestArguments): Promise; + delete(args?: RestArgumentsNoBody): Promise; webhooks: { - get(args?: RestArguments): Promise; + get(args?: RestArgumentsNoBody): Promise; }; preview: { - get(args?: RestArguments): Promise; + get(args?: RestArgumentsNoBody): Promise; }; 'audit-logs': { - get(args?: RestArguments): Promise; + get(args?: RestArgumentsNoBody): Promise; }; 'auto-moderation': { rules: { - get(args?: RestArguments): Promise; + get(args?: RestArgumentsNoBody): Promise; post( - args: RestArguments, + args: RestArguments, ): Promise; ( id: string, ): { - get(args?: RestArguments): Promise; + get(args?: RestArgumentsNoBody): Promise; patch( - args: RestArguments, + args: RestArguments, ): Promise; - delete(args?: RestArguments): Promise; + delete(args?: RestArgumentsNoBody): Promise; }; }; }; channels: { - get(args?: RestArguments): Promise; - post( - args: RestArguments, - ): Promise; + get(args?: RestArgumentsNoBody): Promise; + post(args: RestArguments): Promise; patch( - args: RestArguments, + args: RestArguments, ): Promise; }; members: { - get( - args?: RestArguments, - ): Promise; + get(args?: RestArgumentsNoBody): Promise; search: { get( - args: RestArguments, + args: RestArgumentsNoBody, ): Promise; }; '@me': { - patch( - args: RestArguments, - ): Promise; + patch(args: RestArguments): Promise; }; ( id: string, ): { - get(args?: RestArguments): Promise; - put( - args?: RestArguments, - ): Promise; - patch( - args: RestArguments, - ): Promise; - delete(args?: RestArguments): Promise; + get(args?: RestArgumentsNoBody): Promise; + put(args?: RestArguments): Promise; + patch(args: RestArguments): Promise; + delete(args?: RestArgumentsNoBody): Promise; roles(id: string): { - put(args?: RestArguments): Promise; - delete(args?: RestArguments): Promise; + put(args?: RestArgumentsNoBody): Promise; + delete(args?: RestArgumentsNoBody): Promise; }; }; }; threads: { active: { get( - args?: RestArguments, + args?: RestArgumentsNoBody, ): Promise }>>; }; }; roles: { - get(args?: RestArguments): Promise; - post( - args: RestArguments, - ): Promise; + get(args?: RestArgumentsNoBody): Promise; + post(args: RestArguments): Promise; patch( - args: RestArguments, + args: RestArguments, ): Promise; ( id: string, ): { - get(args?: RestArguments): Promise; - patch( - args: RestArguments, - ): Promise; - delete(args?: RestArguments): Promise; + get(args?: RestArgumentsNoBody): Promise; + patch(args: RestArguments): Promise; + delete(args?: RestArgumentsNoBody): Promise; }; }; bans: { - get(args?: RestArguments): Promise; + get(args?: RestArgumentsNoBody): Promise; ( userId: string, ): { - get(args?: RestArguments): Promise; - put( - args?: RestArguments, - ): Promise; - delete(args?: RestArguments): Promise; + get(args?: RestArgumentsNoBody): Promise; + put(args?: RestArguments): Promise; + delete(args?: RestArgumentsNoBody): Promise; }; }; 'bulk-bans': { - post( - args: RestArguments, - ): Promise; + post(args: RestArguments): Promise; }; mfa: { - post( - args: RestArguments, - ): Promise; + post(args: RestArguments): Promise; }; prune: { - get( - args: RestArguments, - ): Promise; - post( - args: RestArguments, - ): Promise; + get(args: RestArgumentsNoBody): Promise; + post(args: RestArguments): Promise; }; regions: { - get(args?: RestArguments): Promise; + get(args?: RestArgumentsNoBody): Promise; }; invites: { - get(args?: RestArguments): Promise; + get(args?: RestArgumentsNoBody): Promise; }; widget: { - get(args?: RestArguments): Promise; + get(args?: RestArgumentsNoBody<{ style?: string }>): Promise; patch( - args: RestArguments, + args: RestArguments, ): Promise; }; 'widget.json': { - get(args?: RestArguments): Promise; + get(args?: RestArgumentsNoBody): Promise; }; 'widget.png': { - get( - args?: RestArguments, - ): Promise; + get(args?: RestArgumentsNoBody): Promise; }; integrations: { - get(args?: RestArguments): Promise; + get(args?: RestArgumentsNoBody): Promise; ( id: string, ): { - delete(args?: RestArguments): Promise; + delete(args?: RestArgumentsNoBody): Promise; }; }; 'vanity-url': { - get(args?: RestArguments): Promise; + get(args?: RestArgumentsNoBody): Promise; }; 'welcome-screen': { - get(args?: RestArguments): Promise; + get(args?: RestArgumentsNoBody): Promise; patch( - args: RestArguments, + args: RestArguments, ): Promise; }; // onboarding: { - // get(args:RestArguments); + // get(args:RestArgumentsNoBody); // } emojis: { - get(args?: RestArguments): Promise; - post( - args: RestArguments, - ): Promise; + get(args?: RestArgumentsNoBody): Promise; + post(args: RestArguments): Promise; ( id: string, ): { - get(args?: RestArguments): Promise; - patch( - args: RestArguments, - ): Promise; - delete(args?: RestArguments): Promise; + get(args?: RestArgumentsNoBody): Promise; + patch(args: RestArguments): Promise; + delete(args?: RestArgumentsNoBody): Promise; }; }; 'voice-states': { '@me': { patch( - args: RestArguments, + args: RestArguments, ): Promise; - get(args?: RestArguments): Promise; + get(args?: RestArgumentsNoBody): Promise; }; ( userId: string, ): { patch( - args: RestArguments, + args: RestArguments, ): Promise; - get(args?: RestArguments): Promise; + get(args?: RestArgumentsNoBody): Promise; }; }; stickers: { - get(args?: RestArguments): Promise; + get(args?: RestArgumentsNoBody): Promise; post( args: RestArguments< - ProxyRequestMethod.Post, Omit, - object, OmitInsert[] >, ): Promise; ( id: string, ): { - get(args?: RestArguments): Promise; - patch( - args: RestArguments, - ): Promise; - delete(args?: RestArguments): Promise; + get(args?: RestArgumentsNoBody): Promise; + patch(args: RestArguments): Promise; + delete(args?: RestArgumentsNoBody): Promise; }; }; 'scheduled-events': { get( - args?: RestArguments, + args?: RestArgumentsNoBody, ): Promise; post( - args: RestArguments, + args: RestArguments, ): Promise; ( id: string, ): { get( - args?: RestArguments, + args?: RestArgumentsNoBody, ): Promise; patch( - args: RestArguments, + args: RestArguments, ): Promise; - delete(args?: RestArguments): Promise; + delete(args?: RestArgumentsNoBody): Promise; users: { get( - args?: RestArguments, + args?: RestArgumentsNoBody, ): Promise; }; }; }; templates: { - get(args?: RestArguments): Promise; - post( - args: RestArguments, - ): Promise; + get(args?: RestArgumentsNoBody): Promise; + post(args: RestArguments): Promise; ( code: string, ): { - put(args?: RestArguments): Promise; - patch( - args: RestArguments, - ): Promise; - delete(args?: RestArguments): Promise; + put(args?: RestArgumentsNoBody): Promise; + patch(args: RestArguments): Promise; + delete(args?: RestArgumentsNoBody): Promise; }; }; }; diff --git a/src/api/Routes/index.ts b/src/api/Routes/index.ts index e860383..9c5be88 100644 --- a/src/api/Routes/index.ts +++ b/src/api/Routes/index.ts @@ -12,14 +12,15 @@ import type { WebhookRoutes } from './webhooks'; export * from './cdn'; -export type APIRoutes = ApplicationRoutes & - ChannelRoutes & - GatewayRoutes & - GuildRoutes & - InteractionRoutes & - InviteRoutes & - StageInstanceRoutes & - StickerRoutes & - UserRoutes & - VoiceRoutes & - WebhookRoutes; +export interface APIRoutes + extends ApplicationRoutes, + ChannelRoutes, + GatewayRoutes, + GuildRoutes, + InteractionRoutes, + InviteRoutes, + StageInstanceRoutes, + StickerRoutes, + UserRoutes, + VoiceRoutes, + WebhookRoutes {} diff --git a/src/api/Routes/interactions.ts b/src/api/Routes/interactions.ts index 61a0eeb..7638416 100644 --- a/src/api/Routes/interactions.ts +++ b/src/api/Routes/interactions.ts @@ -1,9 +1,9 @@ +import type { OmitInsert } from '../../common'; import type { RESTPostAPIInteractionCallbackJSONBody, RESTPostAPIInteractionCallbackQuery, RESTPostAPIInteractionCallbackResult, } from '../../types'; -import type { ProxyRequestMethod } from '../Router'; import type { RestArguments } from '../api'; export interface InteractionRoutes { @@ -11,24 +11,18 @@ export interface InteractionRoutes { callback: { post( args: RestArguments< - ProxyRequestMethod.Post, RESTPostAPIInteractionCallbackJSONBody, - Omit & { with_response: true } + OmitInsert >, ): Promise; post( args: RestArguments< - ProxyRequestMethod.Post, RESTPostAPIInteractionCallbackJSONBody, - Omit & { with_response: false } + OmitInsert >, ): Promise; post( - args: RestArguments< - ProxyRequestMethod.Post, - RESTPostAPIInteractionCallbackJSONBody, - RESTPostAPIInteractionCallbackQuery - >, + args: RestArguments, ): Promise; }; }; diff --git a/src/api/Routes/invites.ts b/src/api/Routes/invites.ts index c285ce4..16949e2 100644 --- a/src/api/Routes/invites.ts +++ b/src/api/Routes/invites.ts @@ -1,10 +1,9 @@ import type { RESTDeleteAPIInviteResult, RESTGetAPIInviteQuery, RESTGetAPIInviteResult } from '../../types'; -import type { ProxyRequestMethod } from '../Router'; -import type { RestArguments } from '../api'; +import type { RestArguments, RestArgumentsNoBody } from '../api'; export interface InviteRoutes { invites(id: string): { - get(args?: RestArguments): Promise; - delete(args?: RestArguments): Promise; + get(args?: RestArguments): Promise; + delete(args?: RestArgumentsNoBody): Promise; }; } diff --git a/src/api/Routes/skus.ts b/src/api/Routes/skus.ts index a1141c6..ead0c21 100644 --- a/src/api/Routes/skus.ts +++ b/src/api/Routes/skus.ts @@ -3,16 +3,13 @@ import type { RESTGetAPISKUSubscriptionsQuery, RESTGetAPISKUSubscriptionsResult, } from '../../types'; -import type { ProxyRequestMethod } from '../Router'; -import type { RestArguments } from '../api'; +import type { RestArguments, RestArgumentsNoBody } from '../api'; export interface SKuRoutes { skus(id: string): { - get: ( - args?: RestArguments, - ) => Promise; + get: (args?: RestArguments) => Promise; subscriptions(id: string): { - get: (args?: RestArguments) => Promise; + get: (args?: RestArgumentsNoBody) => Promise; }; }; } diff --git a/src/api/Routes/stage-instances.ts b/src/api/Routes/stage-instances.ts index 25a7f9d..1284dea 100644 --- a/src/api/Routes/stage-instances.ts +++ b/src/api/Routes/stage-instances.ts @@ -6,22 +6,17 @@ import type { RESTPostAPIStageInstanceJSONBody, RESTPostAPIStageInstanceResult, } from '../../types'; -import type { ProxyRequestMethod } from '../Router'; -import type { RestArguments } from '../api'; +import type { RestArguments, RestArgumentsNoBody } from '../api'; export interface StageInstanceRoutes { 'stage-instances': { - post( - args: RestArguments, - ): Promise; + post(args: RestArguments): Promise; ( id: string, ): { - get(args?: RestArguments): Promise; - patch( - args: RestArguments, - ): Promise; - delete(args?: RestArguments): Promise; + get(args?: RestArgumentsNoBody): Promise; + patch(args: RestArguments): Promise; + delete(args?: RestArgumentsNoBody): Promise; }; }; } diff --git a/src/api/Routes/stickers.ts b/src/api/Routes/stickers.ts index dd0a3bfc..0a5feaf 100644 --- a/src/api/Routes/stickers.ts +++ b/src/api/Routes/stickers.ts @@ -1,12 +1,11 @@ import type { RESTGetAPIStickerResult, RESTGetStickerPacksResult } from '../../types'; -import type { ProxyRequestMethod } from '../Router'; -import type { RestArguments } from '../api'; +import type { RestArgumentsNoBody } from '../api'; export interface StickerRoutes { stickers(id: string): { - get(args?: RestArguments): Promise; + get(args?: RestArgumentsNoBody): Promise; }; 'sticker-packs': { - get(args?: RestArguments): Promise; + get(args?: RestArgumentsNoBody): Promise; }; } diff --git a/src/api/Routes/users.ts b/src/api/Routes/users.ts index 0bb8b39..03fa262 100644 --- a/src/api/Routes/users.ts +++ b/src/api/Routes/users.ts @@ -14,51 +14,42 @@ import type { RESTPutAPICurrentUserApplicationRoleConnectionJSONBody, RESTPutAPICurrentUserApplicationRoleConnectionResult, } from '../../types'; -import type { ProxyRequestMethod } from '../Router'; -import type { RestArguments } from '../api'; +import type { RestArguments, RestArgumentsNoBody } from '../api'; export interface UserRoutes { users: { ( id: string, ): { - get(args?: RestArguments): Promise; + get(args?: RestArgumentsNoBody): Promise; }; ( id: '@me', ): { - get(args?: RestArguments): Promise; - patch( - args: RestArguments, - ): Promise; + get(args?: RestArgumentsNoBody): Promise; + patch(args: RestArguments): Promise; guilds: { - get( - args?: RestArguments, - ): Promise; + get(args?: RestArgumentsNoBody): Promise; ( id: string, ): { member: { - get(args?: RestArguments): Promise; + get(args?: RestArgumentsNoBody): Promise; }; - delete(args?: RestArguments): Promise; + delete(args?: RestArgumentsNoBody): Promise; }; }; channels: { - post( - args: RestArguments, - ): Promise; + post(args: RestArguments): Promise; }; connections: { - get(args?: RestArguments): Promise; + get(args?: RestArgumentsNoBody): Promise; }; applications(applicationId: string): { 'role-connection': { - get( - args?: RestArguments, - ): Promise; + get(args?: RestArgumentsNoBody): Promise; put( - args: RestArguments, + args: RestArguments, ): Promise; }; }; diff --git a/src/api/Routes/voice.ts b/src/api/Routes/voice.ts index 4fc851a..bb33b5f 100644 --- a/src/api/Routes/voice.ts +++ b/src/api/Routes/voice.ts @@ -1,11 +1,10 @@ import type { RESTGetAPIVoiceRegionsResult } from '../../types'; -import type { ProxyRequestMethod } from '../Router'; -import type { RestArguments } from '../api'; +import type { RestArgumentsNoBody } from '../api'; export interface VoiceRoutes { voice: { region: { - get(args?: RestArguments): Promise; + get(args?: RestArgumentsNoBody): Promise; }; }; } diff --git a/src/api/Routes/webhooks.ts b/src/api/Routes/webhooks.ts index b9ed3e2..4121742 100644 --- a/src/api/Routes/webhooks.ts +++ b/src/api/Routes/webhooks.ts @@ -22,55 +22,38 @@ import type { RESTPostAPIWebhookWithTokenSlackWaitResult, RESTPostAPIWebhookWithTokenWaitResult, } from '../../types'; -import type { ProxyRequestMethod } from '../Router'; -import type { RestArguments } from '../api'; +import type { RestArguments, RestArgumentsNoBody } from '../api'; export interface WebhookRoutes { webhooks(id: string): { - get(args?: RestArguments): Promise; - patch( - args: RestArguments, - ): Promise; - delete(args?: RestArguments): Promise; + get(args?: RestArgumentsNoBody): Promise; + patch(args: RestArguments): Promise; + delete(args?: RestArgumentsNoBody): Promise; ( token: string, ): { - get(args?: RestArguments): Promise; - patch( - args: RestArguments, - ): Promise; - delete(args?: RestArguments): Promise; + get(args?: RestArgumentsNoBody): Promise; + patch(args: RestArguments): Promise; + delete(args?: RestArgumentsNoBody): Promise; post( - args: RestArguments< - ProxyRequestMethod.Post, - RESTPostAPIWebhookWithTokenJSONBody, - RESTPostAPIWebhookWithTokenQuery - >, + args: RestArguments, ): Promise; slack: { post( - args: RestArguments< - ProxyRequestMethod.Post, - RESTPostAPIWebhookWithTokenJSONBody, - RESTPostAPIWebhookWithTokenSlackQuery - >, + args: RestArguments, ): Promise; }; github: { post( - args: RestArguments< - ProxyRequestMethod.Post, - RESTPostAPIWebhookWithTokenJSONBody, - RESTPostAPIWebhookWithTokenGitHubQuery - >, + args: RestArguments, ): Promise; }; - messages: (id: (string & {}) | '@original') => { - get(args?: RestArguments): Promise; + messages: (id: string) => { + get(args?: RestArgumentsNoBody<{ thread_id: string }>): Promise; patch( - args: RestArguments, + args: RestArguments, ): Promise; - delete(args?: RestArguments): Promise; + delete(args?: RestArgumentsNoBody): Promise; }; }; }; diff --git a/src/api/api.ts b/src/api/api.ts index 8089b14..3795f0f 100644 --- a/src/api/api.ts +++ b/src/api/api.ts @@ -1,8 +1,9 @@ -import { randomUUID } from 'node:crypto'; +import { type UUID, randomUUID } from 'node:crypto'; import { Logger, delay, lazyLoadPackage, snowflakeToTimestamp } from '../common'; import type { WorkerData } from '../websocket'; import type { WorkerSendApiRequest } from '../websocket/discord/worker'; -import { CDNRouter, type ProxyRequestMethod } from './Router'; +import { CDNRouter, Router } from './Router'; +import type { APIRoutes } from './Routes'; import { Bucket } from './bucket'; import { type ApiHandlerInternalOptions, @@ -18,13 +19,18 @@ import { isBufferLike } from './utils/utils'; let parentPort: import('node:worker_threads').MessagePort; let workerData: WorkerData; +export interface ApiHandler { + /* @internal */ + _proxy_?: APIRoutes; + debugger?: Logger; +} + export class ApiHandler { options: ApiHandlerInternalOptions; globalBlock = false; ratelimits = new Map(); readyQueue: (() => void)[] = []; cdn = CDNRouter.createProxy(); - debugger?: Logger; workerPromises?: Map any; reject: (error: any) => any }>; constructor(options: ApiHandlerOptions) { @@ -52,6 +58,10 @@ export class ApiHandler { } } + get proxy() { + return (this._proxy_ ??= new Router(this).createProxy()); + } + globalUnblock() { this.globalBlock = false; let cb: (() => void) | undefined; @@ -60,13 +70,13 @@ export class ApiHandler { } } - #randomUUID(): string { + #randomUUID(): UUID { const uuid = randomUUID(); if (this.workerPromises!.has(uuid)) return this.#randomUUID(); return uuid; } - async request( + async request( method: HttpMethods, url: `/${string}`, { auth = true, ...request }: ApiRequestOptions = {}, @@ -412,28 +422,25 @@ export class ApiHandler { } export type RequestOptions = Pick; -export type RequestObject< - M extends ProxyRequestMethod, - B = Record, - Q = Record, - F extends RawFile[] = RawFile[], -> = { - query?: Q; -} & RequestOptions & - (M extends `${ProxyRequestMethod.Get}` - ? unknown - : { - body?: B; - files?: F; - }); export type RestArguments< - M extends ProxyRequestMethod, - B = any, - Q extends never | Record = any, + B extends Record | undefined, + Q extends never | Record = never, F extends RawFile[] = RawFile[], -> = M extends ProxyRequestMethod.Get - ? Q extends never - ? RequestObject - : never - : RequestObject; +> = ( + | { + body: B; + files?: F; + } + | (Q extends never | undefined + ? {} + : { + query?: Q; + }) +) & + RequestOptions; + +export type RestArgumentsNoBody = never> = { + query?: Q; + files?: RawFile[]; +} & RequestOptions; diff --git a/src/builders/Attachment.ts b/src/builders/Attachment.ts index 5130e0e..8396f2a 100644 --- a/src/builders/Attachment.ts +++ b/src/builders/Attachment.ts @@ -184,7 +184,7 @@ export async function resolveAttachmentData( if (data instanceof AttachmentBuilder) { if (!data.data.resolvable) throw new Error('The attachment type has been expressed as attachment but cannot be resolved as one.'); - return { data: data.data.resolvable! }; + return { data: data.data.resolvable }; } switch (type) { diff --git a/src/builders/types.ts b/src/builders/types.ts index 7e099b0..e0d5f28 100644 --- a/src/builders/types.ts +++ b/src/builders/types.ts @@ -11,7 +11,10 @@ export type ComponentCallback< T extends ComponentInteraction | StringSelectMenuInteraction = ComponentInteraction | StringSelectMenuInteraction, > = (interaction: T, stop: ComponentStopCallback, refresh: ComponentRefreshCallback) => any; export type ComponentFilterCallback = (interaction: T) => any; -export type ComponentStopCallback = (reason?: string, refresh?: ComponentRefreshCallback) => any; +export type ComponentStopCallback = ( + reason: 'messageDelete' | 'channelDelete' | 'guildDelete' | (string & {}) | undefined, + refresh: ComponentRefreshCallback, +) => any; export type ComponentRefreshCallback = () => any; export type ModalSubmitCallback = (interaction: T) => any; export type ButtonLink = Omit; @@ -25,5 +28,6 @@ export interface ListenerOptions { timeout?: number; idle?: number; filter?: ComponentFilterCallback; + onPass?: ComponentFilterCallback; onStop?: ComponentStopCallback; } diff --git a/src/cache/adapters/limited.ts b/src/cache/adapters/limited.ts index f9576a1..9b89a8e 100644 --- a/src/cache/adapters/limited.ts +++ b/src/cache/adapters/limited.ts @@ -23,7 +23,6 @@ export interface LimitedMemoryAdapterOptions { role?: ResourceLimitedMemoryAdapter; stage_instance?: ResourceLimitedMemoryAdapter; sticker?: ResourceLimitedMemoryAdapter; - thread?: ResourceLimitedMemoryAdapter; overwrite?: ResourceLimitedMemoryAdapter; message?: ResourceLimitedMemoryAdapter; @@ -125,7 +124,6 @@ export class LimitedMemoryAdapter implements Adapter { case 'role': case 'stage_instance': case 'sticker': - case 'thread': case 'overwrite': case 'message': self.removeToRelationship(namespace, k.split('.')[1]); @@ -221,7 +219,6 @@ export class LimitedMemoryAdapter implements Adapter { case 'role': case 'stage_instance': case 'sticker': - case 'thread': case 'overwrite': case 'message': for (const keyStorage of this.storage.keys()) { diff --git a/src/cache/index.ts b/src/cache/index.ts index 2ab2533..d411598 100644 --- a/src/cache/index.ts +++ b/src/cache/index.ts @@ -13,7 +13,6 @@ import { Presences } from './resources/presence'; import { Roles } from './resources/roles'; import { StageInstances } from './resources/stage-instances'; import { Stickers } from './resources/stickers'; -import { Threads } from './resources/threads'; import { VoiceStates } from './resources/voice-states'; import type { InternalOptions, UsingClient } from '../commands'; @@ -47,7 +46,6 @@ export type GuildBased = 'members' | 'voiceStates'; export type GuildRelated = | 'emojis' | 'roles' - | 'threads' | 'channels' | 'stickers' | 'presences' @@ -114,7 +112,6 @@ export class Cache { overwrites?: Overwrites; roles?: Roles; emojis?: Emojis; - threads?: Threads; channels?: Channels; stickers?: Stickers; presences?: Presences; @@ -165,9 +162,6 @@ export class Cache { if (!this.disabledCache.presences) { this.presences = new Presences(this, client); } - if (!this.disabledCache.threads) { - this.threads = new Threads(this, client); - } if (!this.disabledCache.stageInstances) { this.stageInstances = new StageInstances(this, client); } @@ -200,7 +194,6 @@ export class Cache { this.emojis?.__setClient(client); this.stickers?.__setClient(client); this.presences?.__setClient(client); - this.threads?.__setClient(client); this.stageInstances?.__setClient(client); this.messages?.__setClient(client); this.bans?.__setClient(client); @@ -282,7 +275,6 @@ export class Cache { } break; case 'roles': - case 'threads': case 'stickers': case 'channels': case 'presences': @@ -352,7 +344,6 @@ export class Cache { for (const [type, data, id, guildId] of keys) { switch (type) { case 'roles': - case 'threads': case 'stickers': case 'channels': case 'presences': @@ -444,7 +435,6 @@ export class Cache { for (const [type, data, id, guildId] of keys) { switch (type) { case 'roles': - case 'threads': case 'stickers': case 'channels': case 'presences': @@ -589,11 +579,11 @@ export class Cache { case 'THREAD_CREATE': case 'THREAD_UPDATE': - if (event.d.guild_id) await this.threads?.set(event.d.id, event.d.guild_id, event.d); + if (event.d.guild_id) await this.channels?.set(event.d.id, event.d.guild_id, event.d); break; case 'THREAD_DELETE': - await this.threads?.remove(event.d.id, event.d.guild_id); + await this.channels?.remove(event.d.id, event.d.guild_id); break; case 'USER_UPDATE': diff --git a/src/cache/resources/default/guild-related.ts b/src/cache/resources/default/guild-related.ts index 9bc5e21..f29f0e6 100644 --- a/src/cache/resources/default/guild-related.ts +++ b/src/cache/resources/default/guild-related.ts @@ -1,11 +1,10 @@ -import type { BaseClient } from '../../../client/base'; import type { UsingClient } from '../../../commands'; import { fakePromise } from '../../../common'; import type { GatewayIntentBits } from '../../../types'; import type { Cache, ReturnCache } from '../../index'; export class GuildRelatedResource { - client!: BaseClient; + client!: UsingClient; namespace = 'base'; constructor( diff --git a/src/cache/resources/guilds.ts b/src/cache/resources/guilds.ts index 9af9192..058e510 100644 --- a/src/cache/resources/guilds.ts +++ b/src/cache/resources/guilds.ts @@ -54,7 +54,6 @@ export class Guilds extends BaseResource { return this.cache.users && rawMessage?.user_id ? fakePromise(this.cache.adapter.get(this.cache.users.hashId(rawMessage.user_id)) as APIUser | undefined).then( user => { - return user ? Transformers.Message(this.client, { ...rawMessage!, author: user }) : undefined; + return user ? Transformers.Message(this.client, { ...rawMessage, author: user }) : undefined; }, ) : undefined; @@ -44,7 +44,7 @@ export class Messages extends GuildRelatedResource { ? fakePromise( this.cache.adapter.get(this.cache.users.hashId(rawMessage.user_id)) as APIUser | undefined, ).then(user => { - return user ? Transformers.Message(this.client, { ...rawMessage!, author: user }) : undefined; + return user ? Transformers.Message(this.client, { ...rawMessage, author: user }) : undefined; }) : undefined; }) @@ -59,7 +59,7 @@ export class Messages extends GuildRelatedResource { override values(channel: string): ReturnCache { return fakePromise(super.values(channel) as APIMessageResource[]).then(messages => { const hashes: (string | undefined)[] = this.cache.users - ? messages.map(x => (x.user_id ? this.cache.users!.hashId(x.user_id) : undefined)) + ? messages.map(x => (x.user_id ? this.cache.users?.hashId(x.user_id) : undefined)) : []; return fakePromise(this.cache.adapter.bulkGet(hashes.filter(Boolean) as string[]) as APIUser[]).then(users => { return messages diff --git a/src/cache/resources/threads.ts b/src/cache/resources/threads.ts deleted file mode 100644 index bd8f3dc..0000000 --- a/src/cache/resources/threads.ts +++ /dev/null @@ -1,44 +0,0 @@ -import type { ReturnCache } from '../..'; -import { type ThreadChannelStructure, Transformers } from '../../client/transformers'; -import { fakePromise } from '../../common'; -import type { APIThreadChannel } from '../../types'; -import { GuildRelatedResource } from './default/guild-related'; - -export class Threads extends GuildRelatedResource { - namespace = 'thread'; - - //@ts-expect-error - filter(data: APIThreadChannel, id: string, guild_id?: string) { - return true; - } - - override get(id: string): ReturnCache { - return fakePromise(super.get(id)).then(rawThread => - rawThread ? Transformers.ThreadChannel(this.client, rawThread) : undefined, - ); - } - - raw(id: string): ReturnCache { - return super.get(id); - } - - override bulk(ids: string[]): ReturnCache { - return fakePromise(super.bulk(ids) as APIThreadChannel[]).then(threads => - threads.map(rawThread => Transformers.ThreadChannel(this.client, rawThread)), - ); - } - - bulkRaw(ids: string[]): ReturnCache { - return super.bulk(ids); - } - - override values(guild: string): ReturnCache { - return fakePromise(super.values(guild) as APIThreadChannel[]).then(threads => - threads.map(rawThread => Transformers.ThreadChannel(this.client, rawThread)), - ); - } - - valuesRaw(guild: string): ReturnCache { - return super.values(guild); - } -} diff --git a/src/client/base.ts b/src/client/base.ts index 3ba8b0f..b2c034e 100644 --- a/src/client/base.ts +++ b/src/client/base.ts @@ -1,5 +1,5 @@ import { join } from 'node:path'; -import { type APIRoutes, ApiHandler, Router } from '../api'; +import { ApiHandler } from '../api'; import type { Adapter } from '../cache'; import { Cache, MemoryAdapter } from '../cache'; import type { @@ -57,7 +57,6 @@ import type { MessageStructure } from './transformers'; export class BaseClient { rest!: ApiHandler; - proxy!: APIRoutes; cache!: Cache; applications = new ApplicationShorter(this); @@ -169,6 +168,10 @@ export class BaseClient { ); } + get proxy() { + return this.rest.proxy; + } + set botId(id: string) { this._botId = id; } @@ -188,7 +191,6 @@ export class BaseClient { setServices({ rest, cache, langs, middlewares, handleCommand }: ServicesOptions) { if (rest) { this.rest = rest; - this.proxy = new Router(this.rest).createProxy(); } if (cache) { const caches: (keyof Cache['disabledCache'])[] = [ @@ -204,7 +206,6 @@ export class BaseClient { 'roles', 'stageInstances', 'stickers', - 'threads', 'users', 'voiceStates', ]; @@ -233,8 +234,9 @@ export class BaseClient { this.middlewares = middlewares; } if (langs) { - if (langs.default) this.langs!.defaultLang = langs.default; - if (langs.aliases) this.langs!.aliases = Object.entries(langs.aliases); + this.langs ??= new LangsHandler(this.logger); + if (langs.default) this.langs.defaultLang = langs.default; + if (langs.aliases) this.langs.aliases = Object.entries(langs.aliases); } if (handleCommand) this.handleCommand = new handleCommand(this); @@ -273,7 +275,6 @@ export class BaseClient { domain: 'https://discord.com', debug, }); - this.proxy = new Router(this.rest).createProxy(); } if (this.cache) { diff --git a/src/client/transformers.ts b/src/client/transformers.ts index 5619e61..eb28f93 100644 --- a/src/client/transformers.ts +++ b/src/client/transformers.ts @@ -30,6 +30,7 @@ import { Webhook, WebhookMessage, } from '../structures'; +import { Entitlement } from '../structures/Entitlement'; import { GuildBan } from '../structures/GuildBan'; import type { ChannelType } from '../types'; @@ -63,6 +64,7 @@ export type UserStructure = InferCustomStructure; export type VoiceStateStructure = InferCustomStructure; export type WebhookStructure = InferCustomStructure; export type OptionResolverStructure = InferCustomStructure; +export type EntitlementStructure = InferCustomStructure; export const Transformers = { AnonymousGuild(...args: ConstructorParameters): AnonymousGuildStructure { @@ -157,6 +159,9 @@ export const Transformers = { OptionResolver(...args: ConstructorParameters): OptionResolverStructure { return new OptionResolver(...args); }, + Entitlement(...args: ConstructorParameters): EntitlementStructure { + return new Entitlement(...args); + }, }; export type InferCustomStructure = CustomStructures extends Record ? P : T; diff --git a/src/commands/applications/chatcontext.ts b/src/commands/applications/chatcontext.ts index d4bb278..03e9073 100644 --- a/src/commands/applications/chatcontext.ts +++ b/src/commands/applications/chatcontext.ts @@ -60,28 +60,46 @@ export class CommandContext< return this.resolver.fullCommandName; } - async write( + async write( body: InteractionCreateBodyRequest, - fetchReply?: FR, - ): Promise> { - if (this.interaction) return this.interaction.write(body, fetchReply); + withResponse?: WR, + ): Promise< + When< + WR, + WebhookMessageStructure | When, + void | WebhookMessageStructure | When + > + > { + if (this.interaction) return this.interaction.write(body, withResponse); const options = (this.client as Client | WorkerClient).options?.commands; return (this.messageResponse = await (this.message! as Message)[ !this.messageResponse && options?.reply?.(this) ? 'reply' : 'write' - ](body)); + ](body)) as never; } - async deferReply(ephemeral = false) { - if (this.interaction) return this.interaction.deferReply(ephemeral ? MessageFlags.Ephemeral : undefined); + async deferReply( + ephemeral = false, + withResponse?: WR, + ): Promise< + When< + WR, + WebhookMessageStructure | When, + When | undefined + > + > { + if (this.interaction) + return this.interaction.deferReply(ephemeral ? MessageFlags.Ephemeral : undefined, withResponse); const options = (this.client as Client | WorkerClient).options?.commands; return (this.messageResponse = await (this.message! as Message)[options?.reply?.(this) ? 'reply' : 'write']( options?.deferReplyResponse?.(this) ?? { content: 'Thinking...' }, - )); + )) as never; } - async editResponse(body: InteractionMessageUpdateBodyRequest) { + async editResponse( + body: InteractionMessageUpdateBodyRequest, + ): Promise> { if (this.interaction) return this.interaction.editResponse(body); - return (this.messageResponse = await this.messageResponse!.edit(body)); + return (this.messageResponse = await this.messageResponse!.edit(body)) as never; } deleteResponse() { @@ -89,15 +107,21 @@ export class CommandContext< return this.messageResponse!.delete(); } - editOrReply( + editOrReply( body: InteractionCreateBodyRequest | InteractionMessageUpdateBodyRequest, - fetchReply?: FR, - ): Promise> { - if (this.interaction) return this.interaction.editOrReply(body as InteractionCreateBodyRequest, fetchReply); + withResponse?: WR, + ): Promise< + When< + WR, + WebhookMessageStructure | When, + void | WebhookMessageStructure | When + > + > { + if (this.interaction) return this.interaction.editOrReply(body as InteractionCreateBodyRequest, withResponse); if (this.messageResponse) { return this.editResponse(body); } - return this.write(body as InteractionCreateBodyRequest, fetchReply); + return this.write(body as InteractionCreateBodyRequest, withResponse); } async fetchResponse(): Promise< diff --git a/src/commands/applications/entrycontext.ts b/src/commands/applications/entrycontext.ts index 3b3f2c9..7d4eb44 100644 --- a/src/commands/applications/entrycontext.ts +++ b/src/commands/applications/entrycontext.ts @@ -42,18 +42,18 @@ export class EntryPointContext ex return this.command.name; } - write( + write( body: InteractionCreateBodyRequest, - fetchReply?: FR, - ): Promise> { - return this.interaction.write(body, fetchReply); + withResponse?: WR, + ): Promise> { + return this.interaction.write(body, withResponse); } modal(body: ModalCreateBodyRequest) { return this.interaction.modal(body); } - deferReply(ephemeral = false) { + deferReply(ephemeral = false): Promise> { return this.interaction.deferReply(ephemeral ? MessageFlags.Ephemeral : undefined); } @@ -65,11 +65,11 @@ export class EntryPointContext ex return this.interaction.deleteResponse(); } - editOrReply( + editOrReply( body: InteractionCreateBodyRequest | InteractionMessageUpdateBodyRequest, - fetchReply?: FR, - ): Promise> { - return this.interaction.editOrReply(body as InteractionCreateBodyRequest, fetchReply); + withResponse?: WR, + ): Promise> { + return this.interaction.editOrReply(body as InteractionCreateBodyRequest, withResponse); } fetchResponse() { diff --git a/src/commands/applications/menucontext.ts b/src/commands/applications/menucontext.ts index cf1e5d1..53c33e7 100644 --- a/src/commands/applications/menucontext.ts +++ b/src/commands/applications/menucontext.ts @@ -67,18 +67,18 @@ export class MenuCommandContext< return this.command.name; } - write( + write( body: InteractionCreateBodyRequest, - fetchReply?: FR, - ): Promise> { - return this.interaction.write(body, fetchReply); + withResponse?: WR, + ): Promise> { + return this.interaction.write(body, withResponse); } modal(body: ModalCreateBodyRequest) { return this.interaction.modal(body); } - deferReply(ephemeral = false) { + deferReply(ephemeral = false): Promise> { return this.interaction.deferReply(ephemeral ? MessageFlags.Ephemeral : undefined); } @@ -90,11 +90,11 @@ export class MenuCommandContext< return this.interaction.deleteResponse(); } - editOrReply( + editOrReply( body: InteractionCreateBodyRequest | InteractionMessageUpdateBodyRequest, - fetchReply?: FR, - ): Promise> { - return this.interaction.editOrReply(body as InteractionCreateBodyRequest, fetchReply); + withResponse?: WR, + ): Promise> { + return this.interaction.editOrReply(body as InteractionCreateBodyRequest, withResponse); } fetchResponse() { diff --git a/src/common/it/utils.ts b/src/common/it/utils.ts index 7e43145..4c5aa94 100644 --- a/src/common/it/utils.ts +++ b/src/common/it/utils.ts @@ -345,8 +345,10 @@ export async function resolveEmoji(emoji: EmojiResolvable, cache: Cache): Promis return fromCache && { animated: fromCache.animated, id: fromCache.id, name: fromCache.name }; } - const fromCache = await cache.emojis?.get(emoji.id!); - if (fromCache) return { animated: fromCache.animated, id: fromCache.id, name: fromCache.name }; + if (emoji.id) { + const fromCache = await cache.emojis?.get(emoji.id); + if (fromCache) return { animated: fromCache.animated, id: fromCache.id, name: fromCache.name }; + } return; } diff --git a/src/common/shorters/application.ts b/src/common/shorters/application.ts index f13f968..d4c0730 100644 --- a/src/common/shorters/application.ts +++ b/src/common/shorters/application.ts @@ -1,4 +1,4 @@ -import { Entitlement } from '../../structures/Entitlement'; +import { Transformers } from '../../client'; import type { APIEntitlement, RESTGetAPIEntitlementsQuery, @@ -46,7 +46,7 @@ export class ApplicationShorter extends BaseShorter { return this.client.proxy .applications(applicationId) .entitlements.get({ query }) - .then(et => et.map(e => new Entitlement(this.client, e))); + .then(et => et.map(e => Transformers.Entitlement(this.client, e))); } /** @@ -67,7 +67,7 @@ export class ApplicationShorter extends BaseShorter { return this.client.proxy .applications(applicationId) .entitlements.post({ body }) - .then(et => new Entitlement(this.client, et as APIEntitlement)); + .then(et => Transformers.Entitlement(this.client, et as APIEntitlement)); } /** diff --git a/src/common/shorters/bans.ts b/src/common/shorters/bans.ts index e404acd..5f50eac 100644 --- a/src/common/shorters/bans.ts +++ b/src/common/shorters/bans.ts @@ -57,7 +57,7 @@ export class BanShorter extends BaseShorter { } ban = await this.client.proxy.guilds(guildId).bans(userId).get(); - await this.client.cache.members?.set(ban.user!.id, guildId, ban); + await this.client.cache.members?.set(ban.user.id, guildId, ban); return Transformers.GuildBan(this.client, ban, guildId); } @@ -78,7 +78,7 @@ export class BanShorter extends BaseShorter { query, }); await this.client.cache.bans?.set( - bans.map<[string, APIBan]>(x => [x.user!.id, x]), + bans.map<[string, APIBan]>(x => [x.user.id, x]), guildId, ); return bans.map(m => Transformers.GuildBan(this.client, m, guildId)); diff --git a/src/common/shorters/channels.ts b/src/common/shorters/channels.ts index 1911024..80f0c95 100644 --- a/src/common/shorters/channels.ts +++ b/src/common/shorters/channels.ts @@ -50,9 +50,9 @@ export class ChannelShorter extends BaseShorter { * @returns A Promise that resolves to the deleted channel. */ async delete(id: string, optional: ChannelShorterOptionalParams = { guildId: '@me' }): Promise { - const options = MergeOptions({ guildId: '@me' }, optional); + const options = MergeOptions>({ guildId: '@me' }, optional); const res = await this.client.proxy.channels(id).delete({ reason: options.reason }); - await this.client.cache.channels?.removeIfNI(BaseChannel.__intent__(options.guildId!), res.id, options.guildId!); + await this.client.cache.channels?.removeIfNI(BaseChannel.__intent__(options.guildId), res.id, options.guildId); return channelFrom(res, this.client); } @@ -70,7 +70,7 @@ export class ChannelShorter extends BaseShorter { ): Promise { const options = MergeOptions>({ guildId: '@me' }, optional); const res = await this.client.proxy.channels(id).patch({ body, reason: options.reason }); - await this.client.cache.channels?.setIfNI(BaseChannel.__intent__(options.guildId!), res.id, options.guildId!, res); + await this.client.cache.channels?.setIfNI(BaseChannel.__intent__(options.guildId), res.id, options.guildId, res); if (body.permission_overwrites && 'permission_overwrites' in res && res.permission_overwrites) await this.client.cache.overwrites?.setIfNI( BaseChannel.__intent__(options.guildId), diff --git a/src/common/shorters/guilds.ts b/src/common/shorters/guilds.ts index 59a1001..be0ed50 100644 --- a/src/common/shorters/guilds.ts +++ b/src/common/shorters/guilds.ts @@ -58,12 +58,7 @@ export class GuildShorter extends BaseShorter { * @returns The generated widget URL. */ widgetURL(id: string, style?: GuildWidgetStyle) { - const query = new URLSearchParams(); - if (style) { - query.append('style', style); - } - - return this.client.proxy.guilds(id).widget.get({ query }); + return this.client.proxy.guilds(id).widget.get({ query: { style } }); } async edit(guildId: string, body: RESTPatchAPIGuildJSONBody, reason?: string) { diff --git a/src/common/shorters/interaction.ts b/src/common/shorters/interaction.ts index be225a8..a061e35 100644 --- a/src/common/shorters/interaction.ts +++ b/src/common/shorters/interaction.ts @@ -4,7 +4,7 @@ import type { InteractionMessageUpdateBodyRequest, MessageWebhookCreateBodyReque import { BaseShorter } from './base'; export class InteractionShorter extends BaseShorter { - async reply(id: string, token: string, body: ReplyInteractionBody) { + async reply(id: string, token: string, body: ReplyInteractionBody, withResponse = false) { //@ts-expect-error const { files, ...rest } = body.data ?? {}; //@ts-expect-error @@ -22,6 +22,7 @@ export class InteractionShorter extends BaseShorter { this.client, ), files: parsedFiles, + query: { with_response: withResponse }, }); } @@ -50,16 +51,16 @@ export class InteractionShorter extends BaseShorter { return this.editMessage(token, '@original', body); } - deleteResponse(interactionId: string, token: string, messageId: string) { + deleteResponse(token: string, messageId: string) { return this.client.proxy .webhooks(this.client.applicationId)(token) .messages(messageId) .delete() - .then(() => this.client.components?.onMessageDelete(messageId === '@original' ? interactionId : messageId)); + .then(() => this.client.components?.deleteValue(messageId, 'messageDelete')); } - deleteOriginal(interactionId: string, token: string) { - return this.deleteResponse(interactionId, token, '@original'); + deleteOriginal(token: string) { + return this.deleteResponse(token, '@original'); } async followup(token: string, { files, ...body }: MessageWebhookCreateBodyRequest) { diff --git a/src/common/shorters/members.ts b/src/common/shorters/members.ts index 6652d8f..4da2dd5 100644 --- a/src/common/shorters/members.ts +++ b/src/common/shorters/members.ts @@ -53,21 +53,20 @@ export class MemberShorter extends BaseShorter { query, }); await this.client.cache.members?.set( - members.map(x => [x.user!.id, x]), + members.map(x => [x.user.id, x] as [string, APIGuildMember]), guildId, ); - return members.map(m => Transformers.GuildMember(this.client, m, m.user!, guildId)); + return members.map(m => Transformers.GuildMember(this.client, m, m.user, guildId)); } /** * Unbans a member from the guild. * @param guildId The ID of the guild. * @param memberId The ID of the member to unban. - * @param body The request body for unbanning the member. * @param reason The reason for unbanning the member. */ - async unban(guildId: string, memberId: string, body?: RESTPutAPIGuildBanJSONBody, reason?: string) { - await this.client.proxy.guilds(guildId).bans(memberId).delete({ reason, body }); + async unban(guildId: string, memberId: string, reason?: string) { + await this.client.proxy.guilds(guildId).bans(memberId).delete({ reason }); } /** @@ -104,7 +103,7 @@ export class MemberShorter extends BaseShorter { async edit(guildId: string, memberId: string, body: RESTPatchAPIGuildMemberJSONBody, reason?: string) { const member = await this.client.proxy.guilds(guildId).members(memberId).patch({ body, reason }); await this.client.cache.members?.setIfNI('GuildMembers', memberId, guildId, member); - return Transformers.GuildMember(this.client, member, member.user!, guildId); + return Transformers.GuildMember(this.client, member, member.user, guildId); } /** @@ -124,9 +123,9 @@ export class MemberShorter extends BaseShorter { return; } - await this.client.cache.members?.setIfNI('GuildMembers', member.user!.id, guildId, member); + await this.client.cache.members?.setIfNI('GuildMembers', member.user.id, guildId, member); - return Transformers.GuildMember(this.client, member, member.user!, guildId); + return Transformers.GuildMember(this.client, member, member.user, guildId); } /** @@ -169,8 +168,8 @@ export class MemberShorter extends BaseShorter { members = await this.client.proxy.guilds(guildId).members.get({ query, }); - await this.client.cache.members?.set(members.map(x => [x.user!.id, x]) as [string, APIGuildMember][], guildId); - return members.map(m => Transformers.GuildMember(this.client, m, m.user!, guildId)); + await this.client.cache.members?.set(members.map(x => [x.user.id, x]) as [string, APIGuildMember][], guildId); + return members.map(m => Transformers.GuildMember(this.client, m, m.user, guildId)); } /** @@ -180,7 +179,7 @@ export class MemberShorter extends BaseShorter { * @param id The ID of the role to add. */ addRole(guildId: string, memberId: string, id: string) { - return this.client.proxy.guilds(guildId).members(memberId).roles(id).put({}); + return this.client.proxy.guilds(guildId).members(memberId).roles(id).put(); } /** * Removes a role from a guild member. diff --git a/src/common/shorters/messages.ts b/src/common/shorters/messages.ts index c71bce6..cb89c26 100644 --- a/src/common/shorters/messages.ts +++ b/src/common/shorters/messages.ts @@ -65,7 +65,7 @@ export class MessageShorter extends BaseShorter { .delete({ reason }) .then(async () => { await this.client.cache.messages?.removeIfNI('GuildMessages', messageId, channelId); - this.client.components?.onMessageDelete(messageId); + this.client.components?.deleteValue(messageId, 'messageDelete'); }); } diff --git a/src/common/shorters/templates.ts b/src/common/shorters/templates.ts index a4d0abf..3662f22 100644 --- a/src/common/shorters/templates.ts +++ b/src/common/shorters/templates.ts @@ -28,7 +28,7 @@ export class TemplateShorter extends BaseShorter { return this.client.proxy .guilds(guildId) .templates(code) - .put({}) + .put() .then(template => Transformers.GuildTemplate(this.client, template)); } diff --git a/src/common/shorters/threads.ts b/src/common/shorters/threads.ts index 43a8d98..80fd9d0 100644 --- a/src/common/shorters/threads.ts +++ b/src/common/shorters/threads.ts @@ -1,6 +1,7 @@ import type { ThreadChannelStructure } from '../../client/transformers'; import { channelFrom } from '../../structures'; import type { + APIThreadChannel, APIThreadMember, RESTGetAPIChannelThreadMembersQuery, RESTGetAPIChannelThreadsArchivedQuery, @@ -29,7 +30,15 @@ export class ThreadShorter extends BaseShorter { .channels(channelId) .threads.post({ body, reason }) // When testing this, discord returns the thread object, but in discord api types it does not. - .then(thread => channelFrom(thread, this.client) as ThreadChannelStructure) + .then(async thread => { + await this.client.cache.channels?.setIfNI( + 'Guilds', + thread.id, + (thread as APIThreadChannel).guild_id!, + thread, + ); + return channelFrom(thread, this.client) as ThreadChannelStructure; + }) ); } @@ -44,30 +53,33 @@ export class ThreadShorter extends BaseShorter { .channels(channelId) .messages(messageId) .threads.post({ body, reason }) - .then(thread => channelFrom(thread, this.client) as ThreadChannelStructure); + .then(async thread => { + await this.client.cache.channels?.setIfNI('Guilds', thread.id, (thread as APIThreadChannel).guild_id!, thread); + return channelFrom(thread, this.client) as ThreadChannelStructure; + }); } - async join(threadId: string) { + join(threadId: string) { return this.client.proxy.channels(threadId)['thread-members']('@me').put(); } - async leave(threadId: string) { + leave(threadId: string) { return this.client.proxy.channels(threadId)['thread-members']('@me').delete(); } - async lock(threadId: string, locked = true, reason?: string) { + lock(threadId: string, locked = true, reason?: string) { return this.edit(threadId, { locked }, reason).then(x => channelFrom(x, this.client) as ThreadChannelStructure); } - async edit(threadId: string, body: RESTPatchAPIChannelJSONBody, reason?: string) { + edit(threadId: string, body: RESTPatchAPIChannelJSONBody, reason?: string) { return this.client.channels.edit(threadId, body, { reason }); } - async removeMember(threadId: string, memberId: string) { + removeMember(threadId: string, memberId: string) { return this.client.proxy.channels(threadId)['thread-members'](memberId).delete(); } - async fetchMember( + fetchMember( threadId: string, memberId: string, with_member: WithMember, @@ -79,11 +91,11 @@ export class ThreadShorter extends BaseShorter { }) as never; } - async addMember(threadId: string, memberId: string) { + addMember(threadId: string, memberId: string) { return this.client.proxy.channels(threadId)['thread-members'](memberId).put(); } - async listMembers( + listMembers( threadId: string, query?: T, ): Promise> { diff --git a/src/common/shorters/webhook.ts b/src/common/shorters/webhook.ts index 4577edc..fee71b8 100644 --- a/src/common/shorters/webhook.ts +++ b/src/common/shorters/webhook.ts @@ -146,7 +146,7 @@ export class WebhookShorter extends BaseShorter { const message = await this.client.proxy .webhooks(webhookId)(token) .messages(messageId) - .get({ auth: false, query: { threadId } }); + .get({ auth: false, query: threadId ? { thread_id: threadId } : undefined }); return message ? Transformers.WebhookMessage(this.client, message, webhookId, token) : undefined; } diff --git a/src/components/handler.ts b/src/components/handler.ts index 81bff1a..19b3205 100644 --- a/src/components/handler.ts +++ b/src/components/handler.ts @@ -12,7 +12,9 @@ import type { ModalContext } from './modalcontext'; type COMPONENTS = { components: { match: string | string[] | RegExp; callback: ComponentCallback }[]; options?: ListenerOptions; - messageId?: string; + messageId: string; + channelId: string; + guildId: string | undefined; idle?: NodeJS.Timeout; timeout?: NodeJS.Timeout; __run: (customId: string | string[] | RegExp, callback: ComponentCallback) => any; @@ -20,11 +22,18 @@ type COMPONENTS = { export type CollectorInteraction = ComponentInteraction | StringSelectMenuInteraction; export type ComponentCommands = ComponentCommand | ModalCommand; +export interface CreateComponentCollectorResult { + run( + customId: string | string[] | RegExp, + callback: ComponentCallback, + ): any; + stop(reason?: string): any; +} export class ComponentHandler extends BaseHandler { onFail: OnFailCallback = err => this.logger.warn('.components.onFail', err); readonly values = new Map(); - // 10 minutes timeout, because discord dont send an event when the user cancel the modal + // 10 minutes of timeout by default, because discord doesnt send an event when the user cancels the modal readonly modals = new LimitedCollection({ expire: 60e3 * 10 }); readonly commands: ComponentCommands[] = []; filter = (path: string) => path.endsWith('.js') || (!path.endsWith('.d.ts') && path.endsWith('.ts')); @@ -38,23 +47,22 @@ export class ComponentHandler extends BaseHandler { createComponentCollector( messageId: string, + channelId: string, + guildId: string | undefined, options: ListenerOptions = {}, - ): { - run( - customId: string | string[] | RegExp, - callback: ComponentCallback, - ): any; - stop(reason?: string): any; - } { + ): CreateComponentCollectorResult { this.values.set(messageId, { - components: [], + messageId, + channelId, + guildId, options, + components: [], idle: options.idle && options.idle > 0 ? setTimeout(() => { this.deleteValue(messageId); options.onStop?.('idle', () => { - this.createComponentCollector(messageId, options); + this.createComponentCollector(messageId, channelId, guildId, options); }); }, options.idle) : undefined, @@ -63,7 +71,7 @@ export class ComponentHandler extends BaseHandler { ? setTimeout(() => { this.deleteValue(messageId); options.onStop?.('timeout', () => { - this.createComponentCollector(messageId, options); + this.createComponentCollector(messageId, channelId, guildId, options); }); }, options.timeout) : undefined, @@ -83,7 +91,7 @@ export class ComponentHandler extends BaseHandler { stop: (reason?: string) => { this.deleteValue(messageId); options.onStop?.(reason, () => { - this.createComponentCollector(messageId, options); + this.createComponentCollector(messageId, channelId, guildId, options); }); }, }; @@ -98,13 +106,15 @@ export class ComponentHandler extends BaseHandler { }); if (!component) return; if (row.options?.filter) { - if (!(await row.options.filter(interaction))) return; + if (!(await row.options.filter(interaction))) return row.options.onPass?.(interaction); } row.idle?.refresh(); await component.callback( interaction, reason => { - row.options?.onStop?.(reason ?? 'stop'); + row.options?.onStop?.(reason ?? 'stop', () => { + this.createComponentCollector(row.messageId, row.channelId, row.guildId, row.options); + }); this.deleteValue(id); }, () => { @@ -143,17 +153,15 @@ export class ComponentHandler extends BaseHandler { deleteValue(id: string, reason?: string) { const component = this.values.get(id); if (component) { - if (reason !== undefined) component.options?.onStop?.(reason); + component.options?.onStop?.(reason, () => { + this.createComponentCollector(component.messageId, component.channelId, component.guildId, component.options); + }); clearTimeout(component.timeout); clearTimeout(component.idle); this.values.delete(id); } } - onMessageDelete(id: string) { - this.deleteValue(id, 'messageDelete'); - } - stablishDefaults(component: ComponentCommands) { component.props ??= this.client.options.commands?.defaults?.props ?? {}; const is = component instanceof ModalCommand ? 'modals' : 'components'; @@ -222,7 +230,7 @@ export class ComponentHandler extends BaseHandler { ); if (!component?.__filePath) return null; delete require.cache[component.__filePath]; - const index = this.client.components.commands.findIndex(x => x.__filePath === component.__filePath!); + const index = this.client.components.commands.findIndex(x => x.__filePath === component.__filePath); if (index === -1) return null; this.client.components.commands.splice(index, 1); const imported = await magicImport(component.__filePath).then(x => x.default ?? x); diff --git a/src/events/handler.ts b/src/events/handler.ts index 9a79a45..6abb746 100644 --- a/src/events/handler.ts +++ b/src/events/handler.ts @@ -12,11 +12,15 @@ import { } from '../common'; import type { ClientEvents } from '../events/hooks'; import * as RawEvents from '../events/hooks'; -import type { - GatewayDispatchPayload, - GatewayMessageCreateDispatch, - GatewayMessageDeleteBulkDispatch, - GatewayMessageDeleteDispatch, +import { + type APIThreadChannel, + ChannelType, + type GatewayChannelDeleteDispatch, + type GatewayDispatchPayload, + type GatewayGuildDeleteDispatch, + type GatewayMessageDeleteBulkDispatch, + type GatewayMessageDeleteDispatch, + type GatewayThreadDeleteDispatch, } from '../types'; import type { ClientEvent, ClientNameEvents, CustomEvents, CustomEventsKeys, EventContext } from './event'; @@ -103,33 +107,78 @@ export class EventHandler extends BaseHandler { async execute(name: GatewayEvents, ...args: [GatewayDispatchPayload, Client | WorkerClient, number]) { switch (name) { - case 'MESSAGE_CREATE': - { - const { d: data } = args[0] as GatewayMessageCreateDispatch; - if (args[1].components?.values.has(data.interaction_metadata?.id ?? data.id)) { - args[1].components.values.get(data.interaction_metadata!.id ?? data.id)!.messageId = data.id; - } - } - break; case 'MESSAGE_DELETE': { + if (!args[1].components?.values.size) break; const { d: data } = args[0] as GatewayMessageDeleteDispatch; - const value = [...(args[1].components?.values ?? [])].find(x => x[1].messageId === data.id); + const value = args[1].components.values.get(data.id); if (value) { - args[1].components!.onMessageDelete(value[0]); + args[1].components.deleteValue(value.messageId, 'messageDelete'); } } break; case 'MESSAGE_DELETE_BULK': { - const { d: data } = args[0] as GatewayMessageDeleteBulkDispatch; - const values = [...(args[1].components?.values ?? [])]; - data.ids.forEach(id => { - const value = values.find(x => x[1].messageId === id); + if (!args[1].components?.values.size) break; + const { d: payload } = args[0] as GatewayMessageDeleteBulkDispatch; + for (const id of payload.ids) { + const value = args[1].components.values.get(id); if (value) { - args[1].components!.onMessageDelete(value[0]); + args[1].components.deleteValue(value.messageId, 'messageDelete'); } - }); + } + } + break; + case 'GUILD_DELETE': + { + if (!args[1].components?.values.size) break; + const { d: payload } = args[0] as GatewayGuildDeleteDispatch; + // ignore unavailable guilds? + if (payload.unavailable) break; + for (const [messageId, value] of args[1].components.values) { + if (value.guildId === payload.id) args[1].components.deleteValue(messageId, 'guildDelete'); + } + } + break; + case 'CHANNEL_DELETE': + { + if (!args[1].components?.values.size) break; + const { d: payload } = args[0] as GatewayChannelDeleteDispatch; + + if (payload.type === ChannelType.DM || payload.type === ChannelType.GroupDM) { + for (const value of args[1].components.values) { + if (payload.id === value[1].channelId) args[1].components.deleteValue(value[0], 'channelDelete'); + } + } else { + if (!payload.guild_id) break; + // this is why we dont recommend to use collectors, use ComponentCommand instead + const channels = await args[1].cache.channels?.valuesRaw(payload.guild_id); + const threads = channels + ?.filter( + x => + [ChannelType.PublicThread, ChannelType.PrivateThread, ChannelType.AnnouncementThread].includes( + x.type, + ) && (x as APIThreadChannel).parent_id === payload.id, + ) + .map(x => x.id); + for (const value of args[1].components.values) { + const channelId = value[1].channelId; + if (payload.id === channelId || threads?.includes(channelId)) { + args[1].components.deleteValue(value[0], 'channelDelete'); + } + } + } + } + break; + case 'THREAD_DELETE': + { + if (!args[1].components?.values.size) break; + const { d: payload } = args[0] as GatewayThreadDeleteDispatch; + for (const value of args[1].components.values) { + if (value[1].channelId === payload.id) { + args[1].components.deleteValue(value[0], 'channelDelete'); + } + } } break; } @@ -166,7 +215,7 @@ export class EventHandler extends BaseHandler { t: name, d: packet, } as GatewayDispatchPayload); - await Event.run(hook, client, shardId); + await (Event.run as any)(hook, client, shardId); } catch (e) { await this.onFail(name, e); } diff --git a/src/events/hooks/entitlement.ts b/src/events/hooks/entitlement.ts index e2f41b8..97b3fe7 100644 --- a/src/events/hooks/entitlement.ts +++ b/src/events/hooks/entitlement.ts @@ -1,15 +1,15 @@ +import { Transformers } from '../../client'; import type { UsingClient } from '../../commands'; -import { Entitlement } from '../../structures/Entitlement'; import type { APIEntitlement } from '../../types'; export const ENTITLEMENT_CREATE = (client: UsingClient, data: APIEntitlement) => { - return new Entitlement(client, data); + return Transformers.Entitlement(client, data); }; export const ENTITLEMENT_UPDATE = (client: UsingClient, data: APIEntitlement) => { - return new Entitlement(client, data); + return Transformers.Entitlement(client, data); }; export const ENTITLEMENT_DELETE = (client: UsingClient, data: APIEntitlement) => { - return new Entitlement(client, data); + return Transformers.Entitlement(client, data); }; diff --git a/src/events/hooks/guild.ts b/src/events/hooks/guild.ts index 62f542b..84ee30c 100644 --- a/src/events/hooks/guild.ts +++ b/src/events/hooks/guild.ts @@ -62,7 +62,7 @@ export const GUILD_INTEGRATIONS_UPDATE = (_self: UsingClient, data: GatewayGuild }; export const GUILD_MEMBER_ADD = (self: UsingClient, data: GatewayGuildMemberAddDispatchData) => { - return Transformers.GuildMember(self, data, data.user!, data.guild_id); + return Transformers.GuildMember(self, data, data.user, data.guild_id); }; export const GUILD_MEMBER_REMOVE = (self: UsingClient, data: GatewayGuildMemberRemoveDispatchData) => { @@ -72,7 +72,7 @@ export const GUILD_MEMBER_REMOVE = (self: UsingClient, data: GatewayGuildMemberR export const GUILD_MEMBERS_CHUNK = (self: UsingClient, data: GatewayGuildMembersChunkDispatchData) => { return { ...toCamelCase(data), - members: data.members.map(x => Transformers.GuildMember(self, x, x.user!, data.guild_id)), + members: data.members.map(x => Transformers.GuildMember(self, x, x.user, data.guild_id)), }; }; diff --git a/src/events/hooks/integration.ts b/src/events/hooks/integration.ts index 044721e..a53d0d5 100644 --- a/src/events/hooks/integration.ts +++ b/src/events/hooks/integration.ts @@ -11,7 +11,7 @@ export const INTEGRATION_CREATE = (self: UsingClient, data: GatewayIntegrationCr return data.user ? { ...toCamelCase(data), - user: Transformers.User(self, data.user!), + user: Transformers.User(self, data.user), } : toCamelCase(data); }; @@ -20,7 +20,7 @@ export const INTEGRATION_UPDATE = (self: UsingClient, data: GatewayIntegrationUp return data.user ? { ...toCamelCase(data), - user: Transformers.User(self, data.user!), + user: Transformers.User(self, data.user), } : toCamelCase(data); }; diff --git a/src/events/hooks/thread.ts b/src/events/hooks/thread.ts index b094378..3ed6375 100644 --- a/src/events/hooks/thread.ts +++ b/src/events/hooks/thread.ts @@ -34,5 +34,5 @@ export const THREAD_UPDATE = async ( self: UsingClient, data: GatewayThreadUpdateDispatchData, ): Promise<[thread: ThreadChannelStructure, old?: ThreadChannelStructure]> => { - return [Transformers.ThreadChannel(self, data), await self.cache.threads?.get(data.id)]; + return [Transformers.ThreadChannel(self, data), (await self.cache.channels?.get(data.id)) as ThreadChannelStructure]; }; diff --git a/src/events/hooks/typing.ts b/src/events/hooks/typing.ts index 082fb46..404e04c 100644 --- a/src/events/hooks/typing.ts +++ b/src/events/hooks/typing.ts @@ -7,7 +7,7 @@ export const TYPING_START = (self: UsingClient, data: GatewayTypingStartDispatch return data.member ? { ...toCamelCase(data), - member: Transformers.GuildMember(self, data.member, data.member.user!, data.guild_id!), + member: Transformers.GuildMember(self, data.member, data.member.user, data.guild_id!), } : toCamelCase(data); }; diff --git a/src/index.ts b/src/index.ts index 119abc9..00f8556 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,3 +1,4 @@ +export * from './client'; import { BaseClient, type BaseClientOptions, @@ -24,9 +25,6 @@ export * from './langs'; export { ShardManager, WorkerManager } from './websocket/discord'; // export * from './structures'; -// -export * from './client'; -/// /** * Creates an event with the specified data and run function. diff --git a/src/structures/GuildMember.ts b/src/structures/GuildMember.ts index 5d6398b..8ca0c55 100644 --- a/src/structures/GuildMember.ts +++ b/src/structures/GuildMember.ts @@ -121,8 +121,7 @@ export class BaseGuildMember extends DiscordBase { return { resolve: (resolve: GuildMemberResolvable) => client.members.resolve(guildId, resolve), search: (query?: RESTGetAPIGuildMembersSearchQuery) => client.members.search(guildId, query), - unban: (id: string, body?: RESTPutAPIGuildBanJSONBody, reason?: string) => - client.members.unban(guildId, id, body, reason), + unban: (id: string, reason?: string) => client.members.unban(guildId, id, reason), ban: (id: string, body?: RESTPutAPIGuildBanJSONBody, reason?: string) => client.members.ban(guildId, id, body, reason), kick: (id: string, reason?: string) => client.members.kick(guildId, id, reason), diff --git a/src/structures/Interaction.ts b/src/structures/Interaction.ts index 36cf1eb..c97340b 100644 --- a/src/structures/Interaction.ts +++ b/src/structures/Interaction.ts @@ -39,11 +39,13 @@ import { type MessageFlags, type RESTAPIAttachment, type RESTPostAPIInteractionCallbackJSONBody, + type RESTPostAPIInteractionCallbackResult, } from '../types'; import type { RawFile } from '../api'; import { ActionRow, Embed, Modal, PollBuilder, resolveAttachment, resolveFiles } from '../builders'; import { + type EntitlementStructure, type GuildRoleStructure, type InteractionGuildMemberStructure, type MessageStructure, @@ -69,7 +71,6 @@ import { } from '../common'; import { mix } from '../deps/mixer'; import { type AllChannels, channelFrom } from './'; -import { Entitlement } from './Entitlement'; import { DiscordBase } from './extra/DiscordBase'; import { PermissionsBitField } from './extra/Permissions'; @@ -100,8 +101,9 @@ export class BaseInteraction< member!: When; channel?: AllChannels; message?: MessageStructure; - replied?: Promise | boolean; + replied?: Promise | boolean; appPermissions?: PermissionsBitField; + entitlements: EntitlementStructure[]; constructor( readonly client: UsingClient, @@ -128,7 +130,7 @@ export class BaseInteraction< } this.user = this.member?.user ?? Transformers.User(client, interaction.user!); - this.entitlements = interaction.entitlements.map(e => new Entitlement(this.client, e)); + this.entitlements = interaction.entitlements.map(e => Transformers.Entitlement(this.client, e)); } static transformBodyRequest( @@ -208,39 +210,54 @@ export class BaseInteraction< return payload as T; } - private async matchReplied(body: ReplyInteractionBody) { + private async matchReplied(body: ReplyInteractionBody, withResponse = false) { if (this.__reply) { //@ts-expect-error const { files, ...rest } = body.data ?? {}; //@ts-expect-error const data = body.data instanceof Modal ? body.data : rest; const parsedFiles = files ? await resolveFiles(files) : undefined; - return (this.replied = this.__reply({ + await (this.replied = this.__reply({ body: BaseInteraction.transformBodyRequest({ data, type: body.type }, parsedFiles, this.client), files: parsedFiles, }).then(() => (this.replied = true))); + return; } - return (this.replied = this.client.interactions.reply(this.id, this.token, body).then(() => (this.replied = true))); + const result = await (this.replied = this.client.interactions.reply(this.id, this.token, body, withResponse)); + this.replied = true; + return result?.resource?.message + ? Transformers.WebhookMessage(this.client, result.resource.message as any, this.id, this.token) + : undefined; } - async reply(body: ReplyInteractionBody) { + async reply( + body: ReplyInteractionBody, + withResponse?: WR, + ): Promise> { if (this.replied) { throw new Error('Interaction already replied'); } - await this.matchReplied(body); + const result = await this.matchReplied(body, withResponse); // @ts-expect-error if (body.data instanceof Modal && body.data.__exec) // @ts-expect-error this.client.components.modals.set(this.user.id, (body.data as Modal).__exec); + return result as never; } - deferReply(flags?: MessageFlags) { - return this.reply({ - type: InteractionResponseType.DeferredChannelMessageWithSource, - data: { - flags, + deferReply( + flags?: MessageFlags, + withResponse = false, + ): Promise> { + return this.reply( + { + type: InteractionResponseType.DeferredChannelMessageWithSource, + data: { + flags, + }, }, - }); + withResponse, + ) as never; } isButton(): this is ButtonInteraction { @@ -377,6 +394,7 @@ export class AutocompleteInteraction extend declare type: InteractionType.ApplicationCommandAutocomplete; declare data: ObjectToLower; options: OptionResolverStructure; + declare entitlements: EntitlementStructure[]; constructor( client: UsingClient, interaction: APIApplicationCommandAutocompleteInteraction, @@ -408,7 +426,7 @@ export class AutocompleteInteraction extend } /** @intenal */ - async reply(..._args: unknown[]) { + async reply(..._args: unknown[]): Promise { throw new Error('Cannot use reply in this interaction'); } } @@ -427,14 +445,15 @@ export class Interaction< async write( body: InteractionCreateBodyRequest, - fetchReply?: FR, + withResponse?: FR, ): Promise> { - (await this.reply({ - type: InteractionResponseType.ChannelMessageWithSource, - data: body, - })) as never; - if (fetchReply) return this.fetchResponse() as never; - return undefined as never; + return this.reply( + { + type: InteractionResponseType.ChannelMessageWithSource, + data: body, + }, + withResponse, + ) as never; } modal(body: ModalCreateBodyRequest) { @@ -469,7 +488,7 @@ export class Interaction< } deleteMessage(messageId: string) { - return this.client.interactions.deleteResponse(this.id, this.token, messageId); + return this.client.interactions.deleteResponse(this.token, messageId); } followup(body: MessageWebhookCreateBodyRequest) { @@ -568,6 +587,7 @@ export class ComponentInteraction< declare channel: AllChannels; declare type: InteractionType.MessageComponent; declare message: MessageStructure; + declare entitlements: EntitlementStructure[]; update(data: ComponentInteractionMessageUpdate) { return this.reply({ diff --git a/src/structures/Message.ts b/src/structures/Message.ts index 84387ff..d8506a8 100644 --- a/src/structures/Message.ts +++ b/src/structures/Message.ts @@ -61,7 +61,7 @@ export class BaseMessage extends DiscordBase { } createComponentCollector(options?: ListenerOptions) { - return this.client.components!.createComponentCollector(this.id, options); + return this.client.components!.createComponentCollector(this.id, this.channelId, this.guildId, options); } get url() { @@ -174,7 +174,7 @@ export class WebhookMessage extends BaseMessage { } fetch() { - return this.api.webhooks(this.webhookId)(this.webhookToken).get({ query: this.thread?.id }); + return this.api.webhooks(this.webhookId)(this.webhookToken).get(); } edit(body: EditMessageWebhook) { diff --git a/src/structures/extra/BaseGuild.ts b/src/structures/extra/BaseGuild.ts index c2fb79c..0fab57e 100644 --- a/src/structures/extra/BaseGuild.ts +++ b/src/structures/extra/BaseGuild.ts @@ -93,11 +93,11 @@ export class BaseGuild extends DiscordBase { */ get shard() { if ('gateway' in this.client) { - return (this.client.gateway as ShardManager).get(this.shardId!) as never; + return (this.client.gateway as ShardManager).get(this.shardId) as never; } if ('shards' in this.client) { - return (this.client as WorkerClient).shards.get(this.shardId!); + return (this.client as WorkerClient).shards.get(this.shardId); } return undefined; } diff --git a/src/types/gateway.ts b/src/types/gateway.ts index c7d874b..9a77e0f 100644 --- a/src/types/gateway.ts +++ b/src/types/gateway.ts @@ -582,7 +582,7 @@ export interface GatewayGuildCreateDispatchData extends APIGuild { * * See https://discord.com/developers/docs/resources/channel#channel-object */ - threads: APIChannel[]; + threads: APIThreadChannel[]; /** * Presences of the members in the guild, will only include non-offline members if the size is greater than `large_threshold` * diff --git a/src/types/payloads/channel.ts b/src/types/payloads/channel.ts index 3482eb0..a91e504 100644 --- a/src/types/payloads/channel.ts +++ b/src/types/payloads/channel.ts @@ -573,7 +573,7 @@ export interface APIMessage { /** * Sent if a thread was started from this message */ - thread?: APIChannel; + thread?: APIThreadChannel; /** * Sent if the message contains components like buttons, action rows, or other interactive components * diff --git a/src/websocket/discord/shard.ts b/src/websocket/discord/shard.ts index 36dcb24..beab8e7 100644 --- a/src/websocket/discord/shard.ts +++ b/src/websocket/discord/shard.ts @@ -364,8 +364,8 @@ export class Shard { calculateSafeRequests(): number { const safeRequests = - this.options.ratelimitOptions!.maxRequestsPerRateLimitTick - - Math.ceil(this.options.ratelimitOptions!.rateLimitResetInterval / this.heart.interval) * 2; + this.options.ratelimitOptions.maxRequestsPerRateLimitTick - + Math.ceil(this.options.ratelimitOptions.rateLimitResetInterval / this.heart.interval) * 2; if (safeRequests < 0) { return 0; diff --git a/src/websocket/discord/workermanager.ts b/src/websocket/discord/workermanager.ts index 0779fc8..eaacbc6 100644 --- a/src/websocket/discord/workermanager.ts +++ b/src/websocket/discord/workermanager.ts @@ -1,6 +1,6 @@ import cluster, { type Worker as ClusterWorker } from 'node:cluster'; import { randomUUID } from 'node:crypto'; -import { ApiHandler, Logger, Router } from '../..'; +import { ApiHandler, Logger } from '../..'; import { type Adapter, MemoryAdapter } from '../../cache'; import { BaseClient, type InternalRuntimeConfig } from '../../client/base'; import { type MakePartial, MergeOptions, lazyLoadPackage } from '../../common'; @@ -15,7 +15,7 @@ export class WorkerManager extends Map< number, (ClusterWorker | import('node:worker_threads').Worker | { ready: boolean }) & { ready?: boolean } > { - options!: MakePartial, 'adapter'>; + options: MakePartial, 'adapter'>; debugger?: Logger; connectQueue!: ConnectQueue; workerQueue: (() => void)[] = []; @@ -424,7 +424,7 @@ export class WorkerManager extends Map< domain: 'https://discord.com', debug: this.options.debug, }); - this.options.info ??= await new Router(this.rest).createProxy().gateway.bot.get(); + this.options.info ??= await this.rest.proxy.gateway.bot.get(); this.options.shardEnd ??= this.options.totalShards ?? this.options.info.shards; this.options.totalShards ??= this.options.shardEnd; this.options = MergeOptions>(WorkerManagerDefaults, this.options); diff --git a/tsconfig.json b/tsconfig.json index 39c45a2..eddba28 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -30,7 +30,9 @@ }, "exclude": [ "**/lib", - "**/__test__" + "**/__test__", + "**/node_modules", + "**/.*/" ], "include": [ "src"