Compare commits

..

36 Commits

Author SHA1 Message Date
Vlad Frangu
8702978057 chore(rest): release @discordjs/rest@2.4.3 2025-02-11 00:54:31 +02:00
Jiralite
c2b18d6d8b build: bump undici to 6.21.1 2025-02-08 15:39:26 +00:00
Jiralite
519aa3abe8 build: bump discord-api-types to 0.37.119 2025-02-07 21:45:33 +00:00
Naiyar
89c076c89e feat: message forwards (#10733)
* feat: message forwards

* fix: spelling

* feat: add guildId option for forward

* refactor: type

* refactor: do not use ID suffix for resolvables

* Update TextBasedChannel.js

---------

Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
2025-02-07 21:42:30 +00:00
Jiralite
f224a07381 build: modify origin/main to origin/v14 2025-02-06 00:01:27 +00:00
Syed Waheed
8e1e1be0c2 fix(Guild): type error with permissionOverwrites (#10527)
Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
Co-authored-by: Almeida <github@almeidx.dev>
Co-authored-by: Vlad Frangu <me@vladfrangu.dev>
2025-02-04 20:56:10 +02:00
Vlad Frangu
193a5e9e20 types: fix recurrence rule types (#10694)
* types: fix recurrence rule types

* fix: endAt not endsAt

* types: remove fields that cannot be set by the client

* chore: cleanup JS lands too

* chore: missed you

* chore: bite me

---------

Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
2025-02-04 14:06:46 +00:00
ŊʂƓ PRIYANSHU
73c6bc2c36 chore: Add contributors and last commit badges (#10428)
* chore: add new fancy badges

* chore: add util

* style: remove extra space

---------

Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-01-29 15:06:09 +00:00
Naiyar
b7f1ebc334 fix: incorrect relative path (#10734) 2025-01-29 14:51:11 +00:00
Jiralite
92aea94411 style: prettier 2025-01-29 09:48:17 +00:00
Jiralite
41dee5177d feat: Incident Actions (#10727)
* feat: initial commit

* feat: add guild helper

* docs: `guild` is required

* docs(IncidentActions): move to guild

* fix: `incidents_data` is nullable

* fix: method typo

* fix: default to `null`

* fix: use `new Date()`

* docs: note that it is not received over the gateway

* refactor: use transformer

* chore: resolve TODO

* chore: typo

Co-authored-by: Danial Raza <danialrazafb@gmail.com>

* chore: suggestions

Co-authored-by: Almeida <github@almeidx.dev>

* chore: consistency

Co-authored-by: Almeida <github@almeidx.dev>

---------

Co-authored-by: Danial Raza <danialrazafb@gmail.com>
Co-authored-by: Almeida <github@almeidx.dev>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-01-29 09:43:27 +00:00
Jiralite
bbde371324 build: bump discord-api-types to 0.37.118 2025-01-29 09:35:44 +00:00
Jiralite
66b971899a docs: Use link tags to render links on the documentation (#10731)
* docs: use link tags

* docs(DateResolvable): update link

---------

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-01-29 09:29:59 +00:00
Qjuh
43235d43fe feat(website): type parameters links, builtin doc links, default values (#10515)
* feat(website): links to type parameters, builtin doc links in api.json

* feat(website): show default values for params and props in excerpt

* fix: link in jsdoc

---------

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
2025-01-28 13:32:29 +00:00
Amgelo563
31df3d21cd docs(Message): improve message snapshots description (#10709)
* docs(Message): improve message snapshots description

* docs(Message): remove snapshots single entry callout

---------

Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
2025-01-25 19:49:28 +00:00
Almeida
2663d76709 refactor: use throw instead of Promise.reject (#10712)
Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
Co-authored-by: Renegade334 <Renegade334@users.noreply.github.com>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-01-24 09:41:17 +00:00
Danial Raza
44a1e85847 types(ThreadOnlyChannel): remove incorrect messages property (#10708)
* types(ThreadOnlyChannel): remove incorrect `messages` property

Co-authored-by: TÆMBØ <TAEMBO@users.noreply.github.com>

* test: t e s t s

* test: revamp tests

---------

Co-authored-by: TÆMBØ <TAEMBO@users.noreply.github.com>
Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
2025-01-18 07:45:39 +00:00
Danial Raza
d2e1924fa6 types: add undefined to flags for exactOptionalPropertyTypes (#10707) 2025-01-18 07:44:24 +00:00
Naiyar
68dd260dee types: Allow only ephemeral for defer reply (#10696)
* fix(types): remove unusable flags from InteractionDeferReplyOptions

* fix: include flags in WebhookMessageEditOptions

* chore: update jsdoc

* fix: wrong order

* chore: specify the flag

* chore: extend MessageEditOptions

---------

Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
2025-01-18 07:43:13 +00:00
Naiyar
5e66f85f55 feat(PartialGroupDMChannel): add missing properties (#10502)
* fix(PartialGroupDMChannel): add missing ownerId property

* refactor: make ownerID nullable

* feat: add last_message_id & last_pin_timestamp prop

* feat: add component collector methods

* fix: handle null case

Co-authored-by: Vlad Frangu <me@vladfrangu.dev>

---------

Co-authored-by: Vlad Frangu <me@vladfrangu.dev>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-01-14 09:28:10 +00:00
Almeida
46060419a9 refactor: remove data resolver exports (#10701)
refactor!: remove data resolver exports

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-01-13 10:35:40 +00:00
Digital
7c1b73cc69 fix(PresenceUpdate): correctly add user regardless of their properties (#10672)
* fix(PresenceUpdate): correctly add user regardless of their properties

* refactor(PresenceUpdate): reflect partials

* refactor(PresenceUpdate): prettier

* refactor(PresenceUpdate): add import

---------

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-01-13 10:34:19 +00:00
Naiyar
95db597fc8 refactor(IntegrationApplication): move common properties to Application (#10627)
* refactor(IntegrationApplication): move common properties to Application

* fix: remove prop from ClientApplication
2025-01-13 10:33:56 +00:00
Almeida
0047a49b73 types: remove createComponent and createComponentBuilder (#10687)
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-01-13 10:31:58 +00:00
Naiyar
32dff01f29 fix(InteractionResponses): mark replied true for followUps (#10688)
fix: mark replied true for followUps

Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
2025-01-12 22:29:58 +00:00
Danial Raza
efa50fc3fa feat(Subscription): add renewalSkuIds (#10662) 2025-01-09 19:03:50 +00:00
Qjuh
aa61c20ffd feat(website): include reexported members in docs (#10518)
* feat(website): add re-exported members to docs site

* refactor(scripts): rewrite sourceURL for externals

* feat(website): add external badge

---------

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-01-09 19:02:28 +00:00
Jiralite
d48136bee1 chore(discord.js): release discord.js@14.17.3 2025-01-08 00:33:54 +00:00
Jiralite
46bf8f0146 fix(Message): Ensure channel is defined for clean content (#10681)
fix(Message): ensure channel is defined for clean content

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-01-04 17:23:55 +00:00
Danial Raza
7280d4e82e fix: use resolve() for PermissionOverwrites (#10686)
* fix: use `resolve()` for `PermissionOverwrites`

* fix: typo

Co-authored-by: René <contact.9a5d6388@renegade334.me.uk>

---------

Co-authored-by: René <contact.9a5d6388@renegade334.me.uk>
2025-01-04 17:09:05 +00:00
Jiralite
bd2914cc98 chore(discord.js): release discord.js@14.17.2 2025-01-02 00:27:09 +00:00
Jiralite
77804cfd55 fix(InteractionResponses): check correct property for deprecation
Resolves #10676.
2025-01-02 00:07:51 +00:00
Vlad Frangu
8fea3ed978 chore(discord.js): release discord.js@14.17.1 2025-01-02 01:48:25 +02:00
Vlad Frangu
05c63cd9a1 chore(rest): release @discordjs/rest@2.4.2 2025-01-02 01:45:37 +02:00
Jiralite
8d69b24b5c fix: correct guild member banner URL 2025-01-01 23:44:32 +00:00
Vlad Frangu
9baee4b2ce chore(discord.js): release discord.js@14.17.0 2025-01-02 00:29:07 +02:00
81 changed files with 1044 additions and 324 deletions

View File

@@ -9,7 +9,9 @@
<a href="https://www.npmjs.com/package/discord.js"><img src="https://img.shields.io/npm/v/discord.js.svg?maxAge=3600" alt="npm version" /></a>
<a href="https://www.npmjs.com/package/discord.js"><img src="https://img.shields.io/npm/dt/discord.js.svg?maxAge=3600" alt="npm downloads" /></a>
<a href="https://github.com/discordjs/discord.js/actions"><img src="https://github.com/discordjs/discord.js/actions/workflows/test.yml/badge.svg" alt="Tests status" /></a>
<a href="https://codecov.io/gh/discordjs/discord.js" ><img src="https://codecov.io/gh/discordjs/discord.js/branch/main/graph/badge.svg?precision=2" alt="Code coverage" /></a>
<a href="https://github.com/discordjs/discord.js/commits/main"><img src="https://img.shields.io/github/last-commit/discordjs/discord.js.svg?logo=github&logoColor=ffffff" alt="Last commit." /></a>
<a href="https://github.com/discordjs/discord.js/graphs/contributors"><img src="https://img.shields.io/github/contributors/discordjs/discord.js.svg?maxAge=3600&logo=github&logoColor=fff&color=00c7be" alt="contributors" /></a>
<a href="https://codecov.io/gh/discordjs/discord.js"><img src="https://codecov.io/gh/discordjs/discord.js/branch/main/graph/badge.svg?precision=2" alt="Code coverage" /></a>
</p>
<p>
<a href="https://vercel.com/?utm_source=discordjs&utm_campaign=oss"><img src="https://raw.githubusercontent.com/discordjs/discord.js/main/.github/powered-by-vercel.svg" alt="Vercel" /></a>

View File

@@ -18,8 +18,9 @@ export async function Badges({ node }: { readonly node: any }) {
const isAbstract = node.isAbstract;
const isReadonly = node.isReadonly;
const isOptional = node.isOptional;
const isExternal = node.isExternal;
const isAny = isDeprecated || isProtected || isStatic || isAbstract || isReadonly || isOptional;
const isAny = isDeprecated || isProtected || isStatic || isAbstract || isReadonly || isOptional || isExternal;
return isAny ? (
<div className="mb-1 flex gap-3">
@@ -33,6 +34,7 @@ export async function Badges({ node }: { readonly node: any }) {
{isAbstract ? <Badge className="bg-cyan-500/20 text-cyan-500">abstract</Badge> : null}
{isReadonly ? <Badge className="bg-purple-500/20 text-purple-500">readonly</Badge> : null}
{isOptional ? <Badge className="bg-cyan-500/20 text-cyan-500">optional</Badge> : null}
{isExternal ? <Badge className="bg-purple-500/20 text-purple-500">external</Badge> : null}
</div>
) : null;
}

View File

@@ -29,6 +29,7 @@ export async function ParameterNode({
{description ? <Badges node={parameter} /> : null}
{parameter.name}
{parameter.isOptional ? '?' : ''}: <ExcerptNode node={parameter.typeExcerpt} version={version} />
{parameter.defaultValue ? ` = ${parameter.defaultValue}` : ''}
</span>
{description && parameter.description?.length ? (
<div className="mt-4 pl-4">

View File

@@ -51,7 +51,13 @@ export async function PropertyNode({
<LinkIcon aria-hidden size={16} />
</Link>
{property.displayName}
{property.isOptional ? '?' : ''} : <ExcerptNode node={property.typeExcerpt} version={version} />
{property.isOptional ? '?' : ''} : <ExcerptNode node={property.typeExcerpt} version={version} />{' '}
{property.summary?.defaultValueBlock.length
? `= ${property.summary.defaultValueBlock.reduce(
(acc: string, def: { kind: string; text: string }) => `${acc}${def.text}`,
'',
)}`
: ''}
</span>
</h3>

View File

@@ -6,19 +6,19 @@
"private": true,
"scripts": {
"build": "turbo run build --concurrency=4",
"build:affected": "turbo run build --filter=...[origin/main] --concurrency=4",
"build:affected": "turbo run build --filter=...[origin/v14] --concurrency=4",
"build:apps": "turbo run build:local --filter=...{apps/*} --concurrency=4",
"build:apps:affected": "turbo run build:local --filter=...{apps/*}[origin/main] --concurrency=4",
"build:apps:affected": "turbo run build:local --filter=...{apps/*}[origin/v14] --concurrency=4",
"test": "turbo run test --concurrency=4",
"test:affected": "turbo run test --filter=...[origin/main] --concurrency=4",
"test:affected": "turbo run test --filter=...[origin/v14] --concurrency=4",
"lint": "turbo run lint --concurrency=4",
"lint:affected": "turbo run lint --filter=...[origin/main] --concurrency=4",
"lint:affected": "turbo run lint --filter=...[origin/v14] --concurrency=4",
"format": "turbo run format --concurrency=4",
"format:affected": "turbo run format --filter=...[origin/main] --concurrency=4",
"format:affected": "turbo run format --filter=...[origin/v14] --concurrency=4",
"fmt": "turbo run format --concurrency=4",
"fmt:affected": "turbo run format --filter=...[origin/main] --concurrency=4",
"fmt:affected": "turbo run format --filter=...[origin/v14] --concurrency=4",
"docs": "turbo run docs --concurrency=4",
"docs:affected": "turbo run docs --filter=...[origin/main] --concurrency=4",
"docs:affected": "turbo run docs --filter=...[origin/v14] --concurrency=4",
"prepare": "is-ci || husky",
"update": "pnpm --recursive update --interactive",
"update:latest": "pnpm --recursive update --interactive --latest",

View File

@@ -49,7 +49,7 @@
"meilisearch": "^0.38.0",
"p-limit": "^6.1.0",
"tslib": "^2.6.3",
"undici": "6.19.8"
"undici": "6.21.1"
},
"devDependencies": {
"@types/node": "^18.19.45",

View File

@@ -14,6 +14,7 @@ import type { IExcerptTokenRange } from './Excerpt.js';
* @public
*/
export interface IApiParameterOptions {
defaultValue: string | undefined;
isOptional: boolean;
isRest: boolean;
parameterName: string;
@@ -124,6 +125,7 @@ export function ApiParameterListMixin<TBaseClass extends IApiItemConstructor>(
isOptional: Boolean(parameterOptions.isOptional),
isRest: Boolean(parameterOptions.isRest),
parent: this,
defaultValue: parameterOptions.defaultValue,
});
this[_parameters].push(parameter);
@@ -171,6 +173,7 @@ export function ApiParameterListMixin<TBaseClass extends IApiItemConstructor>(
parameterTypeTokenRange: parameter.parameterTypeExcerpt.tokenRange,
isOptional: parameter.isOptional,
isRest: parameter.isRest,
defaultValue: parameter.defaultValue,
});
}

View File

@@ -41,6 +41,7 @@ const MinifyJSONMapping = {
constraintTokenRange: 'ctr',
dependencies: 'dp',
defaultTypeTokenRange: 'dtr',
defaultValue: 'dv',
docComment: 'd',
endIndex: 'en',
excerptTokens: 'ex',

View File

@@ -262,6 +262,7 @@ function mapParam(
startIndex: 1 + index + paramTokens.slice(0, index).reduce((akk, num) => akk + num, 0),
endIndex: 1 + index + paramTokens.slice(0, index + 1).reduce((akk, num) => akk + num, 0),
},
defaultValue: param.default,
};
}

View File

@@ -12,6 +12,7 @@ import type { Excerpt } from '../mixins/Excerpt.js';
* @public
*/
export interface IParameterOptions {
defaultValue: string | undefined;
isOptional: boolean;
isRest: boolean;
name: string;
@@ -56,6 +57,11 @@ export class Parameter {
*/
public isRest: boolean;
/**
* The default value for this parameter if optional
*/
public defaultValue: string | undefined;
private readonly _parent: ApiParameterListMixin;
public constructor(options: IParameterOptions) {
@@ -64,6 +70,7 @@ export class Parameter {
this.isOptional = options.isOptional;
this.isRest = options.isRest;
this._parent = options.parent;
this.defaultValue = options.defaultValue;
}
/**

View File

@@ -843,6 +843,7 @@ export class ApiModelGenerator {
const parameters: IApiParameterOptions[] = this._captureParameters(
nodesToCapture,
functionDeclaration.parameters,
jsDoc?.params,
);
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, nodesToCapture);
@@ -1043,6 +1044,7 @@ export class ApiModelGenerator {
const parameters: IApiParameterOptions[] = this._captureParameters(
nodesToCapture,
methodDeclaration.parameters,
jsDoc?.params,
);
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, nodesToCapture);
@@ -1137,7 +1139,11 @@ export class ApiModelGenerator {
methodSignature.typeParameters,
);
const parameters: IApiParameterOptions[] = this._captureParameters(nodesToCapture, methodSignature.parameters);
const parameters: IApiParameterOptions[] = this._captureParameters(
nodesToCapture,
methodSignature.parameters,
jsDoc?.params,
);
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, nodesToCapture);
const apiItemMetadata: ApiItemMetadata = this._collector.fetchApiItemMetadata(astDeclaration);
@@ -1342,7 +1348,7 @@ export class ApiModelGenerator {
const apiItemMetadata: ApiItemMetadata = this._collector.fetchApiItemMetadata(astDeclaration);
const docComment: tsdoc.DocComment | undefined = jsDoc
? this._tsDocParser.parseString(
`/**\n * ${this._fixLinkTags(jsDoc.description) ?? ''}${jsDoc.default ? ` (default: ${this._escapeSpecialChars(jsDoc.default)})` : ''}\n${
`/**\n * ${this._fixLinkTags(jsDoc.description) ?? ''}${jsDoc.default ? `\n * @defaultValue ${this._escapeSpecialChars(jsDoc.default)}` : ''}\n${
'see' in jsDoc ? jsDoc.see.map((see) => ` * @see ${see}\n`).join('') : ''
}${'readonly' in jsDoc && jsDoc.readonly ? ' * @readonly\n' : ''}${
'deprecated' in jsDoc && jsDoc.deprecated
@@ -1529,6 +1535,7 @@ export class ApiModelGenerator {
},
isOptional: Boolean(parameter.optional),
isRest: parameter.name.startsWith('...'),
defaultValue: parameter.default?.toString(),
});
excerptTokens.push(...newTokens);
excerptTokens.push({
@@ -1548,6 +1555,7 @@ export class ApiModelGenerator {
},
isOptional: Boolean(parameter.optional),
isRest: parameter.name.startsWith('...'),
defaultValue: parameter.default?.toString(),
});
excerptTokens.push(...newTokens);
excerptTokens.push({
@@ -1640,6 +1648,7 @@ export class ApiModelGenerator {
private _captureParameters(
nodesToCapture: IExcerptBuilderNodeToCapture[],
parameterNodes: ts.NodeArray<ts.ParameterDeclaration>,
jsDoc?: DocgenParamJson[] | undefined,
): IApiParameterOptions[] {
const parameters: IApiParameterOptions[] = [];
for (const parameter of parameterNodes) {
@@ -1650,6 +1659,9 @@ export class ApiModelGenerator {
parameterTypeTokenRange,
isOptional: this._collector.typeChecker.isOptionalParameter(parameter),
isRest: Boolean(parameter.dotDotDotToken),
defaultValue:
parameter.initializer?.getText() ??
jsDoc?.find((param) => param.name === parameter.name.getText().trim())?.default?.toString(),
});
}
@@ -1753,7 +1765,7 @@ export class ApiModelGenerator {
return input;
}
return input.replaceAll(/(?<char>[{}])/g, '\\$<char>');
return input.replaceAll(/(?<char>[@{}])/g, '\\$<char>');
}
private _fixLinkTags(input?: string): string | undefined {
@@ -1848,7 +1860,7 @@ export class ApiModelGenerator {
isOptional: Boolean(prop.nullable),
isReadonly: Boolean(prop.readonly),
docComment: this._tsDocParser.parseString(
`/**\n * ${this._fixLinkTags(prop.description) ?? ''}${prop.default ? ` (default: ${this._escapeSpecialChars(prop.default)})` : ''}\n${
`/**\n * ${this._fixLinkTags(prop.description) ?? ''}\n${prop.default ? ` * @defaultValue ${this._escapeSpecialChars(prop.default)}\n` : ''}${
prop.see?.map((see) => ` * @see ${see}\n`).join('') ?? ''
}${prop.readonly ? ' * @readonly\n' : ''} */`,
).docComment,
@@ -1860,7 +1872,7 @@ export class ApiModelGenerator {
}${prop.name} :`,
},
...mappedVarType,
{ kind: ExcerptTokenKind.Content, text: ';' },
{ kind: ExcerptTokenKind.Content, text: `${prop.default ? ` = ${prop.default}` : ''};` },
],
propertyTypeTokenRange: { startIndex: 1, endIndex: 1 + mappedVarType.length },
releaseTag: prop.access === 'private' ? ReleaseTag.Internal : ReleaseTag.Public,
@@ -1883,6 +1895,7 @@ export class ApiModelGenerator {
startIndex: 1 + index + paramTokens.slice(0, index).reduce((akk, num) => akk + num, 0),
endIndex: 1 + index + paramTokens.slice(0, index + 1).reduce((akk, num) => akk + num, 0),
},
defaultValue: param.default?.toString(),
};
}
@@ -1907,7 +1920,7 @@ export class ApiModelGenerator {
excerptTokens.push(...newTokens);
excerptTokens.push({
kind: ExcerptTokenKind.Content,
text: `, ${method.params![index + 1]!.name}${
text: `${method.params![index]!.default ? ` = ${method.params![index]!.default}` : ''}, ${method.params![index + 1]!.name}${
method.params![index + 1]!.nullable || method.params![index + 1]!.optional ? '?' : ''
}: `,
});
@@ -1917,7 +1930,10 @@ export class ApiModelGenerator {
const newTokens = this._mapVarType(method.params[method.params.length - 1]!.type);
paramTokens.push(newTokens.length);
excerptTokens.push(...newTokens);
excerptTokens.push({ kind: ExcerptTokenKind.Content, text: `): ` });
excerptTokens.push({
kind: ExcerptTokenKind.Content,
text: `${method.params![method.params.length - 1]!.default ? ` = ${method.params![method.params.length - 1]!.default}` : ''}): `,
});
}
const returnTokens = this._mapVarType(method.returns?.[0] ?? []);

View File

@@ -9,7 +9,8 @@
<a href="https://www.npmjs.com/package/@discordjs/brokers"><img src="https://img.shields.io/npm/v/@discordjs/brokers.svg?maxAge=3600" alt="npm version" /></a>
<a href="https://www.npmjs.com/package/@discordjs/brokers"><img src="https://img.shields.io/npm/dt/@discordjs/brokers.svg?maxAge=3600" alt="npm downloads" /></a>
<a href="https://github.com/discordjs/discord.js/actions"><img src="https://github.com/discordjs/discord.js/actions/workflows/test.yml/badge.svg" alt="Build status" /></a>
<a href="https://codecov.io/gh/discordjs/discord.js" ><img src="https://codecov.io/gh/discordjs/discord.js/branch/main/graph/badge.svg?precision=2&flag=brokers" alt="Code coverage" /></a>
<a href="https://github.com/discordjs/discord.js/commits/main/packages/brokers"><img alt="Last commit." src="https://img.shields.io/github/last-commit/discordjs/discord.js?logo=github&logoColor=ffffff&path=packages%2Fbrokers"></a>
<a href="https://codecov.io/gh/discordjs/discord.js"><img src="https://codecov.io/gh/discordjs/discord.js/branch/main/graph/badge.svg?precision=2&flag=brokers" alt="Code coverage" /></a>
</p>
<p>
<a href="https://vercel.com/?utm_source=discordjs&utm_campaign=oss"><img src="https://raw.githubusercontent.com/discordjs/discord.js/main/.github/powered-by-vercel.svg" alt="Vercel" /></a>

View File

@@ -9,7 +9,8 @@
<a href="https://www.npmjs.com/package/@discordjs/builders"><img src="https://img.shields.io/npm/v/@discordjs/builders.svg?maxAge=3600" alt="npm version" /></a>
<a href="https://www.npmjs.com/package/@discordjs/builders"><img src="https://img.shields.io/npm/dt/@discordjs/builders.svg?maxAge=3600" alt="npm downloads" /></a>
<a href="https://github.com/discordjs/discord.js/actions"><img src="https://github.com/discordjs/discord.js/actions/workflows/test.yml/badge.svg" alt="Build status" /></a>
<a href="https://codecov.io/gh/discordjs/discord.js" ><img src="https://codecov.io/gh/discordjs/discord.js/branch/main/graph/badge.svg?precision=2&flag=builders" alt="Code coverage" /></a>
<a href="https://github.com/discordjs/discord.js/commits/main/packages/builders"><img alt="Last commit." src="https://img.shields.io/github/last-commit/discordjs/discord.js?logo=github&logoColor=ffffff&path=packages%2Fbuilders"></a>
<a href="https://codecov.io/gh/discordjs/discord.js"><img src="https://codecov.io/gh/discordjs/discord.js/branch/main/graph/badge.svg?precision=2&flag=builders" alt="Code coverage" /></a>
</p>
<p>
<a href="https://vercel.com/?utm_source=discordjs&utm_campaign=oss"><img src="https://raw.githubusercontent.com/discordjs/discord.js/main/.github/powered-by-vercel.svg" alt="Vercel" /></a>

View File

@@ -68,7 +68,7 @@
"@discordjs/formatters": "workspace:^",
"@discordjs/util": "workspace:^",
"@sapphire/shapeshift": "^4.0.0",
"discord-api-types": "^0.37.114",
"discord-api-types": "^0.37.119",
"fast-deep-equal": "^3.1.3",
"ts-mixer": "^6.0.4",
"tslib": "^2.6.3"

View File

@@ -9,7 +9,8 @@
<a href="https://www.npmjs.com/package/@discordjs/collection"><img src="https://img.shields.io/npm/v/@discordjs/collection.svg?maxAge=3600" alt="npm version" /></a>
<a href="https://www.npmjs.com/package/@discordjs/collection"><img src="https://img.shields.io/npm/dt/@discordjs/collection.svg?maxAge=3600" alt="npm downloads" /></a>
<a href="https://github.com/discordjs/discord.js/actions"><img src="https://github.com/discordjs/discord.js/actions/workflows/test.yml/badge.svg" alt="Build status" /></a>
<a href="https://codecov.io/gh/discordjs/discord.js" ><img src="https://codecov.io/gh/discordjs/discord.js/branch/main/graph/badge.svg?precision=2&flag=collection" alt="Code coverage" /></a>
<a href="https://github.com/discordjs/discord.js/commits/main/packages/collection"><img alt="Last commit." src="https://img.shields.io/github/last-commit/discordjs/discord.js?logo=github&logoColor=ffffff&path=packages%2Fcollection"></a>
<a href="https://codecov.io/gh/discordjs/discord.js"><img src="https://codecov.io/gh/discordjs/discord.js/branch/main/graph/badge.svg?precision=2&flag=collection" alt="Code coverage" /></a>
</p>
<p>
<a href="https://vercel.com/?utm_source=discordjs&utm_campaign=oss"><img src="https://raw.githubusercontent.com/discordjs/discord.js/main/.github/powered-by-vercel.svg" alt="Vercel" /></a>

View File

@@ -9,7 +9,8 @@
<a href="https://www.npmjs.com/package/@discordjs/core"><img src="https://img.shields.io/npm/v/@discordjs/core.svg?maxAge=3600" alt="npm version" /></a>
<a href="https://www.npmjs.com/package/@discordjs/core"><img src="https://img.shields.io/npm/dt/@discordjs/core.svg?maxAge=3600" alt="npm downloads" /></a>
<a href="https://github.com/discordjs/discord.js/actions"><img src="https://github.com/discordjs/discord.js/actions/workflows/test.yml/badge.svg" alt="Build status" /></a>
<a href="https://codecov.io/gh/discordjs/discord.js" ><img src="https://codecov.io/gh/discordjs/discord.js/branch/main/graph/badge.svg?precision=2&flag=core" alt="Code coverage" /></a>
<a href="https://github.com/discordjs/discord.js/commits/main/packages/core"><img alt="Last commit." src="https://img.shields.io/github/last-commit/discordjs/discord.js?logo=github&logoColor=ffffff&path=packages%2Fcore"></a>
<a href="https://codecov.io/gh/discordjs/discord.js"><img src="https://codecov.io/gh/discordjs/discord.js/branch/main/graph/badge.svg?precision=2&flag=core" alt="Code coverage" /></a>
</p>
<p>
<a href="https://vercel.com/?utm_source=discordjs&utm_campaign=oss"><img src="https://raw.githubusercontent.com/discordjs/discord.js/main/.github/powered-by-vercel.svg" alt="Vercel" /></a>

View File

@@ -1,5 +1,6 @@
{
"extends": "../../api-extractor.json",
"bundledPackages": ["discord-api-types"],
"docModel": {
"projectFolderUrl": "https://github.com/discordjs/discord.js/tree/main/packages/core"
}

View File

@@ -70,7 +70,7 @@
"@discordjs/ws": "workspace:^",
"@sapphire/snowflake": "^3.5.3",
"@vladfrangu/async_event_emitter": "^2.4.6",
"discord-api-types": "^0.37.114"
"discord-api-types": "^0.37.119"
},
"devDependencies": {
"@discordjs/api-extractor": "workspace:^",

View File

@@ -7,6 +7,7 @@
<p>
<a href="https://discord.gg/djs"><img src="https://img.shields.io/discord/222078108977594368?color=5865F2&logo=discord&logoColor=white" alt="Discord server" /></a>
<a href="https://github.com/discordjs/discord.js/actions"><img src="https://github.com/discordjs/discord.js/actions/workflows/test.yml/badge.svg" alt="Build status" /></a>
<a href="https://github.com/discordjs/discord.js/commits/main/packages/create-discord-bot"><img alt="Last commit." src="https://img.shields.io/github/last-commit/discordjs/discord.js?logo=github&logoColor=ffffff&path=packages%2Fcreate-discord-bot"></a>
</p>
<p>
<a href="https://vercel.com/?utm_source=discordjs&utm_campaign=oss"><img src="https://raw.githubusercontent.com/discordjs/discord.js/main/.github/powered-by-vercel.svg" alt="Vercel" /></a>

View File

@@ -83,7 +83,7 @@
"no-void": "error",
"no-warning-comments": "warn",
"prefer-promise-reject-errors": "error",
"require-await": "warn",
"require-await": "off",
"wrap-iife": "error",
"yoda": "error",

View File

@@ -2,6 +2,72 @@
All notable changes to this project will be documented in this file.
# [14.17.3](https://github.com/discordjs/discord.js/compare/14.17.2...14.17.3) - (2025-01-08)
## Bug Fixes
- **Message:** Ensure channel is defined for clean content (#10681) ([46bf8f0](https://github.com/discordjs/discord.js/commit/46bf8f0146b67d7c480a3512ade1edbfb16e7a26))
- Use `resolve()` for `PermissionOverwrites` (#10686) ([7280d4e](https://github.com/discordjs/discord.js/commit/7280d4e82eb47ce7cb3964057d7d56a62179cf18))
# [14.17.2](https://github.com/discordjs/discord.js/compare/14.17.1...14.17.2) - (2025-01-02)
## Bug Fixes
- **InteractionResponses:** Check correct property for deprecation ([77804cf](https://github.com/discordjs/discord.js/commit/77804cfd559691d9b8c85aec8c494cd6c14c4ea7))
# [14.17.0](https://github.com/discordjs/discord.js/compare/14.16.3...14.17.0) - (2025-01-01)
## Bug Fixes
- **InteractionResponses:** Do not use `in` if a string is passed ([ff42d7a](https://github.com/discordjs/discord.js/commit/ff42d7af72e940ae72c61d2c5164ae68f2708b96))
- Use Message#interactionMetadata (#10654) ([6087088](https://github.com/discordjs/discord.js/commit/60870885790eb1857ed4c2969c9c404e356a1299))
- **InteractionResponses:** Properly resolve message flags (#10661) ([b2754d4](https://github.com/discordjs/discord.js/commit/b2754d4a0ec250ae84057d0f07c078376f54829c))
- **ThreadChannel:** Make `ownerId` always present (#10618) ([7678f11](https://github.com/discordjs/discord.js/commit/7678f1176a645878261361faef0429f9cf7f4810))
- **MessageReaction:** Address `undefined` burst properties (#10597) ([76968b4](https://github.com/discordjs/discord.js/commit/76968b4bc14b8a66825f9140d130b1e04c11855a))
- **ThreadChannel:** Address parameter type on fetchOwner() (#10592) ([56c9396](https://github.com/discordjs/discord.js/commit/56c9396b717d4dec2410ca13938ce238ec21215d))
- **InteractionResponses:** Throw error on deleting response of unacknowledged interaction (#10587) ([21c283f](https://github.com/discordjs/discord.js/commit/21c283f964ab9e331db53cc0c21ca64980372488))
- **GuildScheduledEvent:** Handle null recurrence_rule (#10543) ([831aafa](https://github.com/discordjs/discord.js/commit/831aafa733e8eea55534c4c39b87775d2e2f56c4))
## Documentation
- Correct discord-api-types URLs (#10622) ([76042f0](https://github.com/discordjs/discord.js/commit/76042f05386edcbadc5ad4ded22e8b15c7b6f8ec))
- Typos (#10628) ([388783d](https://github.com/discordjs/discord.js/commit/388783d7dd718aae519801b90aa781d07b7fb64e))
- Add note about idempotence to role add/remove routes (#10586) ([565fc01](https://github.com/discordjs/discord.js/commit/565fc0192a5ed2642ff1bd615c59678b5c3cd24b))
- **Client:** Fix incorrect managers descriptions ([f79ba52](https://github.com/discordjs/discord.js/commit/f79ba52c7a1334d987e9873a8a411e92d5140116))
- **discord.js:** Remove `utf-8-validate` (#10531) ([297e959](https://github.com/discordjs/discord.js/commit/297e959f48abbfd3af58cc29cdcef139d3579821))
## Features
- **ClientApplication:** Add webhook events (#10588) ([7b2a2e3](https://github.com/discordjs/discord.js/commit/7b2a2e3a154afd69ff892da615ea75c46730f226))
- **InteractionResponses:** Support `with_response` query parameter (#10636) ([622acbc](https://github.com/discordjs/discord.js/commit/622acbcbf02c3b8e0eae4296964c3e745e19378d))
- **ClientApplication:** Add webhook events (#10588) ([ae1deac](https://github.com/discordjs/discord.js/commit/ae1deac2bf37aecda4c044bf5c28d03930bd763b))
- **EntitlementManager:** Support get entitlement (#10606) ([a367e2c](https://github.com/discordjs/discord.js/commit/a367e2c8c99ab3bfb83cdbfb65e7a5020b50b7f7))
- Add subscriptions (#10541) ([4cca33d](https://github.com/discordjs/discord.js/commit/4cca33d9b0759294c9a2dfec39d80a24a2cc1595))
- Emit reaction type on gateway events (#10598) ([bda3128](https://github.com/discordjs/discord.js/commit/bda31284bf46515747e002e86ea35d0b6910e269))
- Voice Channel Effect Send (#10318) ([34343c6](https://github.com/discordjs/discord.js/commit/34343c6afae65205d3b17b60fdd202d0937d6a46))
- **GuildMember:** Banners (#10384) ([b1ded63](https://github.com/discordjs/discord.js/commit/b1ded63e42e7349f535df4680509b9393dd8f288))
- Add ApplicationEmoji to EmojiResolvable and MessageReaction#emoji (#10477) ([1fc87a9](https://github.com/discordjs/discord.js/commit/1fc87a96987fe69722502d7574500926a4e0bfde))
- Recurring scheduled events (#10447) ([97c3237](https://github.com/discordjs/discord.js/commit/97c3237a70027f71bb3f046357a55bb730daca14))
- Message forwarding (#10464) ([c122178](https://github.com/discordjs/discord.js/commit/c12217829b46f7a60266f65af4af19cdbfcd7906))
## Refactor
- **FetchApplicationCommandOptions:** Use `Locale` over `LocaleString` (#10625) ([7ce6f2f](https://github.com/discordjs/discord.js/commit/7ce6f2fc8a8756532d71a542186d10a0aa951471))
- Use `cache.get()` for snowflakes, `resolve()` otherwise (#10626) ([dedaa5d](https://github.com/discordjs/discord.js/commit/dedaa5d657f15491910ec05102ce72affc822b97))
- Remove extra traversing (#10580) ([33533b7](https://github.com/discordjs/discord.js/commit/33533b72849d9741dae8c979734b45abbf3657a7))
- **InteractionResponses:** Deprecate ephemeral response option (#10574) ([be38f57](https://github.com/discordjs/discord.js/commit/be38f5792602ed1a79a9638aa8e629e7ad6bdd0d))
- Deprecate `reason` parameter on adding and removing thread members (#10551) ([72e0c99](https://github.com/discordjs/discord.js/commit/72e0c994547f2a9c99b320870e14d7f1643f3851))
- Deprecate fetching user flags (#10550) ([3d06c9d](https://github.com/discordjs/discord.js/commit/3d06c9d872b2e79356f1239f7d0eb0577a4bcedf))
## Testing
- Remove unused test (#10638) ([53cbb0e](https://github.com/discordjs/discord.js/commit/53cbb0e36d4ab191cbc15a022d752da14c2e0ace))
## Typings
- Add missing `Caches` managers (#10540) ([13471fa](https://github.com/discordjs/discord.js/commit/13471fa1b7c44b236db9fe9b1a64dacd41b14b76))
- Remove newMessage partial on messageUpdate event typing (#10526) ([5faf074](https://github.com/discordjs/discord.js/commit/5faf074c145044f0edefafab97fd07a8dfb8bc30))
# [14.16.3](https://github.com/discordjs/discord.js/compare/14.16.2...14.16.3) - (2024-09-29)
## Bug Fixes

View File

@@ -9,7 +9,8 @@
<a href="https://www.npmjs.com/package/discord.js"><img src="https://img.shields.io/npm/v/discord.js.svg?maxAge=3600" alt="npm version" /></a>
<a href="https://www.npmjs.com/package/discord.js"><img src="https://img.shields.io/npm/dt/discord.js.svg?maxAge=3600" alt="npm downloads" /></a>
<a href="https://github.com/discordjs/discord.js/actions"><img src="https://github.com/discordjs/discord.js/actions/workflows/test.yml/badge.svg" alt="Tests status" /></a>
<a href="https://codecov.io/gh/discordjs/discord.js" ><img src="https://codecov.io/gh/discordjs/discord.js/branch/main/graph/badge.svg?precision=2" alt="Code coverage" /></a>
<a href="https://github.com/discordjs/discord.js/commits/main/packages/discord.js"><img alt="Last commit." src="https://img.shields.io/github/last-commit/discordjs/discord.js?logo=github&logoColor=ffffff&path=packages%2Fdiscord.js"></a>
<a href="https://codecov.io/gh/discordjs/discord.js"><img src="https://codecov.io/gh/discordjs/discord.js/branch/main/graph/badge.svg?precision=2" alt="Code coverage" /></a>
</p>
<p>
<a href="https://vercel.com/?utm_source=discordjs&utm_campaign=oss"><img src="https://raw.githubusercontent.com/discordjs/discord.js/main/.github/powered-by-vercel.svg" alt="Vercel" /></a>

View File

@@ -1,6 +1,14 @@
{
"extends": "../../api-extractor.json",
"mainEntryPointFilePath": "<projectFolder>/typings/index.d.ts",
"bundledPackages": [
"discord-api-types",
"@discordjs/builders",
"@discordjs/formatters",
"@discordjs/rest",
"@discordjs/util",
"@discordjs/ws"
],
"docModel": {
"projectFolderUrl": "https://github.com/discordjs/discord.js/tree/main/packages/discord.js"
}

View File

@@ -1,7 +1,7 @@
{
"$schema": "https://json.schemastore.org/package.json",
"name": "discord.js",
"version": "14.16.3",
"version": "14.17.3",
"description": "A powerful library for interacting with the Discord API",
"scripts": {
"test": "pnpm run docs:test && pnpm run test:typescript",
@@ -72,11 +72,11 @@
"@discordjs/util": "workspace:^",
"@discordjs/ws": "^1.2.0",
"@sapphire/snowflake": "3.5.3",
"discord-api-types": "^0.37.114",
"discord-api-types": "^0.37.119",
"fast-deep-equal": "3.1.3",
"lodash.snakecase": "4.1.1",
"tslib": "^2.6.3",
"undici": "6.19.8"
"undici": "6.21.1"
},
"devDependencies": {
"@discordjs/api-extractor": "workspace:^",

View File

@@ -2,11 +2,14 @@
const Action = require('./Action');
const Events = require('../../util/Events');
const Partials = require('../../util/Partials');
class PresenceUpdateAction extends Action {
handle(data) {
let user = this.client.users.cache.get(data.user.id);
if (!user && data.user.username) user = this.client.users._add(data.user);
if (!user && ('username' in data.user || this.client.options.partials.includes(Partials.User))) {
user = this.client.users._add(data.user);
}
if (!user) return;
if (data.user.username) {

View File

@@ -95,7 +95,8 @@ const Messages = {
[DjsErrorCodes.ChannelNotCached]: 'Could not find the channel where this message came from in the cache!',
[DjsErrorCodes.StageChannelResolve]: 'Could not resolve channel to a stage channel.',
[DjsErrorCodes.GuildScheduledEventResolve]: 'Could not resolve the guild scheduled event.',
[DjsErrorCodes.FetchOwnerId]: type => `Couldn't resolve the ${type} ownerId to fetch the ${type} member.`,
[DjsErrorCodes.FetchOwnerId]: type =>
`Couldn't resolve the ${type} ownerId to fetch the ${type} ${type === 'group DM' ? 'owner' : 'member'}.`,
[DjsErrorCodes.InvalidType]: (name, expected, an = false) => `Supplied ${name} is not a${an ? 'n' : ''} ${expected}.`,
[DjsErrorCodes.InvalidElement]: (type, name, elem) => `Supplied ${type} ${name} includes an invalid element: ${elem}`,

View File

@@ -29,7 +29,6 @@ exports.ChannelFlagsBitField = require('./util/ChannelFlagsBitField');
exports.Collection = require('@discordjs/collection').Collection;
exports.Constants = require('./util/Constants');
exports.Colors = require('./util/Colors');
__exportStar(require('./util/DataResolver.js'), exports);
exports.Events = require('./util/Events');
exports.Formatters = require('./util/Formatters');
exports.GuildMemberFlagsBitField = require('./util/GuildMemberFlagsBitField').GuildMemberFlagsBitField;

View File

@@ -36,8 +36,8 @@ class BaseGuildEmojiManager extends CachedManager {
* @returns {?GuildEmoji}
*/
resolve(emoji) {
if (emoji instanceof ReactionEmoji) return super.cache.get(emoji.id) ?? null;
if (emoji instanceof ApplicationEmoji) return super.cache.get(emoji.id) ?? null;
if (emoji instanceof ReactionEmoji) return this.cache.get(emoji.id) ?? null;
if (emoji instanceof ApplicationEmoji) return this.cache.get(emoji.id) ?? null;
return super.resolve(emoji);
}

View File

@@ -97,14 +97,14 @@ class GuildBanManager extends CachedManager {
* .then(console.log)
* .catch(console.error);
*/
fetch(options) {
async fetch(options) {
if (!options) return this._fetchMany();
const { user, cache, force, limit, before, after } = options;
const resolvedUser = this.client.users.resolveId(user ?? options);
if (resolvedUser) return this._fetchSingle({ user: resolvedUser, cache, force });
if (!before && !after && !limit && cache === undefined) {
return Promise.reject(new DiscordjsError(ErrorCodes.FetchBanResolveId));
throw new DiscordjsError(ErrorCodes.FetchBanResolveId);
}
return this._fetchMany(options);

View File

@@ -84,7 +84,7 @@ class GuildChannelManager extends CachedManager {
* @returns {?(GuildChannel|ThreadChannel)}
*/
resolve(channel) {
if (channel instanceof ThreadChannel) return super.cache.get(channel.id) ?? null;
if (channel instanceof ThreadChannel) return this.cache.get(channel.id) ?? null;
return super.resolve(channel);
}

View File

@@ -39,14 +39,14 @@ class GuildEmojiRoleManager extends DataManager {
* @param {RoleResolvable|RoleResolvable[]|Collection<Snowflake, Role>} roleOrRoles The role or roles to add
* @returns {Promise<GuildEmoji>}
*/
add(roleOrRoles) {
async add(roleOrRoles) {
if (!Array.isArray(roleOrRoles) && !(roleOrRoles instanceof Collection)) roleOrRoles = [roleOrRoles];
const resolvedRoles = [];
for (const role of roleOrRoles.values()) {
const resolvedRole = this.guild.roles.resolveId(role);
if (!resolvedRole) {
return Promise.reject(new DiscordjsTypeError(ErrorCodes.InvalidElement, 'Array or Collection', 'roles', role));
throw new DiscordjsTypeError(ErrorCodes.InvalidElement, 'Array or Collection', 'roles', role);
}
resolvedRoles.push(resolvedRole);
}
@@ -60,14 +60,14 @@ class GuildEmojiRoleManager extends DataManager {
* @param {RoleResolvable|RoleResolvable[]|Collection<Snowflake, Role>} roleOrRoles The role or roles to remove
* @returns {Promise<GuildEmoji>}
*/
remove(roleOrRoles) {
async remove(roleOrRoles) {
if (!Array.isArray(roleOrRoles) && !(roleOrRoles instanceof Collection)) roleOrRoles = [roleOrRoles];
const resolvedRoleIds = [];
for (const role of roleOrRoles.values()) {
const roleId = this.guild.roles.resolveId(role);
if (!roleId) {
return Promise.reject(new DiscordjsTypeError(ErrorCodes.InvalidElement, 'Array or Collection', 'roles', role));
throw new DiscordjsTypeError(ErrorCodes.InvalidElement, 'Array or Collection', 'roles', role);
}
resolvedRoleIds.push(roleId);
}

View File

@@ -121,22 +121,22 @@ class GuildInviteManager extends CachedManager {
* .then(console.log)
* .catch(console.error);
*/
fetch(options) {
async fetch(options) {
if (!options) return this._fetchMany();
if (typeof options === 'string') {
const code = resolveInviteCode(options);
if (!code) return Promise.reject(new DiscordjsError(ErrorCodes.InviteResolveCode));
if (!code) throw new DiscordjsError(ErrorCodes.InviteResolveCode);
return this._fetchSingle({ code, cache: true });
}
if (!options.code) {
if (options.channelId) {
const id = this.guild.channels.resolveId(options.channelId);
if (!id) return Promise.reject(new DiscordjsError(ErrorCodes.GuildChannelResolve));
if (!id) throw new DiscordjsError(ErrorCodes.GuildChannelResolve);
return this._fetchChannelMany(id, options.cache);
}
if ('cache' in options) return this._fetchMany(options.cache);
return Promise.reject(new DiscordjsError(ErrorCodes.InviteResolveCode));
throw new DiscordjsError(ErrorCodes.InviteResolveCode);
}
return this._fetchSingle({
...options,

View File

@@ -18,6 +18,7 @@ const { resolveImage } = require('../util/DataResolver');
const Events = require('../util/Events');
const PermissionsBitField = require('../util/PermissionsBitField');
const SystemChannelFlagsBitField = require('../util/SystemChannelFlagsBitField');
const { _transformAPIIncidentsData } = require('../util/Transformers.js');
const { resolveColor } = require('../util/Util');
let cacheWarningEmitted = false;
@@ -281,6 +282,39 @@ class GuildManager extends CachedManager {
return data.reduce((coll, guild) => coll.set(guild.id, new OAuth2Guild(this.client, guild)), new Collection());
}
/**
* Options used to set incident actions. Supplying `null` to any option will disable the action.
* @typedef {Object} IncidentActionsEditOptions
* @property {?DateResolvable} [invitesDisabledUntil] When invites should be enabled again
* @property {?DateResolvable} [dmsDisabledUntil] When direct messages should be enabled again
*/
/**
* Sets the incident actions for a guild.
* @param {GuildResolvable} guild The guild
* @param {IncidentActionsEditOptions} incidentActions The incident actions to set
* @returns {Promise<IncidentActions>}
*/
async setIncidentActions(guild, { invitesDisabledUntil, dmsDisabledUntil }) {
const guildId = this.resolveId(guild);
const data = await this.client.rest.put(Routes.guildIncidentActions(guildId), {
body: {
invites_disabled_until: invitesDisabledUntil && new Date(invitesDisabledUntil).toISOString(),
dms_disabled_until: dmsDisabledUntil && new Date(dmsDisabledUntil).toISOString(),
},
});
const parsedData = _transformAPIIncidentsData(data);
const resolvedGuild = this.resolve(guild);
if (resolvedGuild) {
resolvedGuild.incidentsData = parsedData;
}
return parsedData;
}
/**
* Returns a URL for the PNG widget of a guild.
* @param {GuildResolvable} guild The guild of the widget image

View File

@@ -54,8 +54,8 @@ class GuildMemberManager extends CachedManager {
resolve(member) {
const memberResolvable = super.resolve(member);
if (memberResolvable) return memberResolvable;
const userResolvable = this.client.users.resolveId(member);
if (userResolvable) return super.cache.get(userResolvable) ?? null;
const userId = this.client.users.resolveId(member);
if (userId) return this.cache.get(userId) ?? null;
return null;
}
@@ -67,8 +67,8 @@ class GuildMemberManager extends CachedManager {
resolveId(member) {
const memberResolvable = super.resolveId(member);
if (memberResolvable) return memberResolvable;
const userResolvable = this.client.users.resolveId(member);
return this.cache.has(userResolvable) ? userResolvable : null;
const userId = this.client.users.resolveId(member);
return this.cache.has(userId) ? userId : null;
}
/**
@@ -223,7 +223,7 @@ class GuildMemberManager extends CachedManager {
return this._add(data, cache);
}
_fetchMany({
async _fetchMany({
limit = 0,
withPresences: presences,
users,
@@ -231,7 +231,7 @@ class GuildMemberManager extends CachedManager {
time = 120e3,
nonce = DiscordSnowflake.generate().toString(),
} = {}) {
if (nonce.length > 32) return Promise.reject(new DiscordjsRangeError(ErrorCodes.MemberFetchNonceLength));
if (nonce.length > 32) throw new DiscordjsRangeError(ErrorCodes.MemberFetchNonceLength);
return new Promise((resolve, reject) => {
if (!query && !users) query = '';
@@ -461,7 +461,7 @@ class GuildMemberManager extends CachedManager {
*/
async kick(user, reason) {
const id = this.client.users.resolveId(user);
if (!id) return Promise.reject(new DiscordjsTypeError(ErrorCodes.InvalidType, 'user', 'UserResolvable'));
if (!id) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'user', 'UserResolvable');
await this.client.rest.delete(Routes.guildMember(this.guild.id, id), { reason });

View File

@@ -41,15 +41,12 @@ class GuildScheduledEventManager extends CachedManager {
* Options for setting a recurrence rule for a guild scheduled event.
* @typedef {Object} GuildScheduledEventRecurrenceRuleOptions
* @property {DateResolvable} startAt The time the recurrence rule interval starts at
* @property {?DateResolvable} endAt The time the recurrence rule interval ends at
* @property {GuildScheduledEventRecurrenceRuleFrequency} frequency How often the event occurs
* @property {number} interval The spacing between the events
* @property {?GuildScheduledEventRecurrenceRuleWeekday[]} byWeekday The days within a week to recur on
* @property {?GuildScheduledEventRecurrenceRuleNWeekday[]} byNWeekday The days within a week to recur on
* @property {?GuildScheduledEventRecurrenceRuleMonth[]} byMonth The months to recur on
* @property {?number[]} byMonthDay The days within a month to recur on
* @property {?number[]} byYearDay The days within a year to recur on
* @property {?number} count The total amount of times the event is allowed to recur before stopping
*/
/**

View File

@@ -62,15 +62,13 @@ class PermissionOverwriteManager extends CachedManager {
* },
* ], 'Needed to change permissions');
*/
set(overwrites, reason) {
async set(overwrites, reason) {
if (!Array.isArray(overwrites) && !(overwrites instanceof Collection)) {
return Promise.reject(
new DiscordjsTypeError(
ErrorCodes.InvalidType,
'overwrites',
'Array or Collection of Permission Overwrites',
true,
),
throw new DiscordjsTypeError(
ErrorCodes.InvalidType,
'overwrites',
'Array or Collection of Permission Overwrites',
true,
);
}
return this.channel.edit({ permissionOverwrites: overwrites, reason });

View File

@@ -97,7 +97,7 @@ class ThreadManager extends CachedManager {
* Data that can be resolved to a Date object. This can be:
* * A Date object
* * A number representing a timestamp
* * An [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) string
* * An {@link https://en.wikipedia.org/wiki/ISO_8601 ISO 8601} string
* @typedef {Date|number|string} DateResolvable
*/

View File

@@ -120,7 +120,7 @@ class Shard extends EventEmitter {
* before resolving (`-1` or `Infinity` for no wait)
* @returns {Promise<ChildProcess>}
*/
spawn(timeout = 30_000) {
async spawn(timeout = 30_000) {
if (this.process) throw new DiscordjsError(ErrorCodes.ShardingProcessExists, this.id);
if (this.worker) throw new DiscordjsError(ErrorCodes.ShardingWorkerExists, this.id);
@@ -161,7 +161,7 @@ class Shard extends EventEmitter {
*/
this.emit(ShardEvents.Spawn, child);
if (timeout === -1 || timeout === Infinity) return Promise.resolve(child);
if (timeout === -1 || timeout === Infinity) return child;
return new Promise((resolve, reject) => {
const cleanup = () => {
clearTimeout(spawnTimeoutTimer);
@@ -260,10 +260,10 @@ class Shard extends EventEmitter {
* .then(count => console.log(`${count} guilds in shard ${shard.id}`))
* .catch(console.error);
*/
fetchClientValue(prop) {
async fetchClientValue(prop) {
// Shard is dead (maybe respawning), don't cache anything and error immediately
if (!this.process && !this.worker) {
return Promise.reject(new DiscordjsError(ErrorCodes.ShardingNoChildExists, this.id));
throw new DiscordjsError(ErrorCodes.ShardingNoChildExists, this.id);
}
// Cached promise from previous call
@@ -302,13 +302,13 @@ class Shard extends EventEmitter {
* @param {*} [context] The context for the eval
* @returns {Promise<*>} Result of the script execution
*/
eval(script, context) {
async eval(script, context) {
// Stringify the script if it's a Function
const _eval = typeof script === 'function' ? `(${script})(this, ${JSON.stringify(context)})` : script;
// Shard is dead (maybe respawning), don't cache anything and error immediately
if (!this.process && !this.worker) {
return Promise.reject(new DiscordjsError(ErrorCodes.ShardingNoChildExists, this.id));
throw new DiscordjsError(ErrorCodes.ShardingNoChildExists, this.id);
}
// Cached promise from previous call

View File

@@ -225,7 +225,8 @@ class ShardClientUtil {
* Emitted when the client encounters an error.
* <warn>Errors thrown within this event do not have a catch handler, it is
* recommended to not use async functions as `error` event handlers. See the
* [Node.js docs](https://nodejs.org/api/events.html#capture-rejections-of-promises) for details.</warn>
* {@link https://nodejs.org/api/events.html#capture-rejections-of-promises Node.js documentation}
* for details.)</warn>
* @event Client#error
* @param {Error} error The error encountered
*/

View File

@@ -256,9 +256,9 @@ class ShardingManager extends EventEmitter {
* @param {BroadcastEvalOptions} [options={}] The options for the broadcast
* @returns {Promise<*|Array<*>>} Results of the script execution
*/
broadcastEval(script, options = {}) {
async broadcastEval(script, options = {}) {
if (typeof script !== 'function') {
return Promise.reject(new DiscordjsTypeError(ErrorCodes.ShardingInvalidEvalBroadcast));
throw new DiscordjsTypeError(ErrorCodes.ShardingInvalidEvalBroadcast);
}
return this._performOnShards('eval', [`(${script})(this, ${JSON.stringify(options.context)})`], options.shard);
}
@@ -285,16 +285,16 @@ class ShardingManager extends EventEmitter {
* @returns {Promise<*|Array<*>>} Results of the method execution
* @private
*/
_performOnShards(method, args, shard) {
if (this.shards.size === 0) return Promise.reject(new DiscordjsError(ErrorCodes.ShardingNoShards));
async _performOnShards(method, args, shard) {
if (this.shards.size === 0) throw new DiscordjsError(ErrorCodes.ShardingNoShards);
if (typeof shard === 'number') {
if (this.shards.has(shard)) return this.shards.get(shard)[method](...args);
return Promise.reject(new DiscordjsError(ErrorCodes.ShardingShardNotFound, shard));
throw new DiscordjsError(ErrorCodes.ShardingShardNotFound, shard);
}
if (this.shards.size !== this.shardList.length) {
return Promise.reject(new DiscordjsError(ErrorCodes.ShardingInProcess));
throw new DiscordjsError(ErrorCodes.ShardingInProcess);
}
const promises = [];

View File

@@ -173,26 +173,6 @@ class ClientApplication extends Application {
this.guildId ??= null;
}
if ('cover_image' in data) {
/**
* The hash of the application's cover image
* @type {?string}
*/
this.cover = data.cover_image;
} else {
this.cover ??= null;
}
if ('rpc_origins' in data) {
/**
* The application's RPC origins, if enabled
* @type {string[]}
*/
this.rpcOrigins = data.rpc_origins;
} else {
this.rpcOrigins ??= [];
}
if ('bot_require_code_grant' in data) {
/**
* If this application's bot requires a code grant when using the OAuth2 flow

View File

@@ -29,6 +29,7 @@ const VoiceStateManager = require('../managers/VoiceStateManager');
const { resolveImage } = require('../util/DataResolver');
const Status = require('../util/Status');
const SystemChannelFlagsBitField = require('../util/SystemChannelFlagsBitField');
const { _transformAPIIncidentsData } = require('../util/Transformers.js');
const { discordSort, getSortableGroupTypes, resolvePartialEmoji } = require('../util/Util');
/**
@@ -470,6 +471,27 @@ class Guild extends AnonymousGuild {
stickers: data.stickers,
});
}
if ('incidents_data' in data) {
/**
* Incident actions of a guild.
* @typedef {Object} IncidentActions
* @property {?Date} invitesDisabledUntil When invites would be enabled again
* @property {?Date} dmsDisabledUntil When direct messages would be enabled again
* @property {?Date} dmSpamDetectedAt When direct message spam was detected
* @property {?Date} raidDetectedAt When a raid was detected
*/
/**
* The incidents data of this guild.
* <info>You will need to fetch the guild using {@link BaseGuild#fetch} if you want to receive
* this property.</info>
* @type {?IncidentActions}
*/
this.incidentsData = data.incidents_data && _transformAPIIncidentsData(data.incidents_data);
} else {
this.incidentsData ??= null;
}
}
/**
@@ -1365,6 +1387,15 @@ class Guild extends AnonymousGuild {
return this.edit({ features });
}
/**
* Sets the incident actions for a guild.
* @param {IncidentActionsEditOptions} incidentActions The incident actions to set
* @returns {Promise<IncidentActions>}
*/
async setIncidentActions(incidentActions) {
return this.client.guilds.setIncidentActions(this.id, incidentActions);
}
/**
* Whether this guild equals another guild. It compares all properties, so for most operations
* it is advisable to just compare `guild.id === guild2.id` as it is much faster and is often

View File

@@ -265,8 +265,8 @@ class GuildChannel extends BaseChannel {
* Locks in the permission overwrites from the parent channel.
* @returns {Promise<GuildChannel>}
*/
lockPermissions() {
if (!this.parent) return Promise.reject(new DiscordjsError(ErrorCodes.GuildChannelOrphan));
async lockPermissions() {
if (!this.parent) throw new DiscordjsError(ErrorCodes.GuildChannelOrphan);
const permissionOverwrites = this.parent.permissionOverwrites.cache.map(overwrite => overwrite.toJSON());
return this.edit({ permissionOverwrites });
}

View File

@@ -9,6 +9,7 @@ const {
MessageType,
MessageFlags,
PermissionFlagsBits,
MessageReferenceType,
} = require('discord-api-types/v10');
const Attachment = require('./Attachment');
const Base = require('./Base');
@@ -452,7 +453,7 @@ class Message extends Base {
if (data.message_snapshots) {
/**
* The message associated with the message reference
* The message snapshots associated with the message reference
* @type {Collection<Snowflake, Message>}
*/
this.messageSnapshots = data.message_snapshots.reduce((coll, snapshot) => {
@@ -590,7 +591,7 @@ class Message extends Base {
*/
get cleanContent() {
// eslint-disable-next-line eqeqeq
return this.content != null ? cleanContent(this.content, this.channel) : null;
return this.content != null && this.channel ? cleanContent(this.content, this.channel) : null;
}
/**
@@ -704,7 +705,11 @@ class Message extends Base {
* @readonly
*/
get editable() {
const precheck = Boolean(this.author.id === this.client.user.id && (!this.guild || this.channel?.viewable));
const precheck = Boolean(
this.author.id === this.client.user.id &&
(!this.guild || this.channel?.viewable) &&
this.reference?.type !== MessageReferenceType.Forward,
);
// Regardless of permissions thread messages cannot be edited if
// the thread is archived or the thread is locked and the bot does not have permission to manage threads.
@@ -824,8 +829,8 @@ class Message extends Base {
* .then(msg => console.log(`Updated the content of a message to ${msg.content}`))
* .catch(console.error);
*/
edit(options) {
if (!this.channel) return Promise.reject(new DiscordjsError(ErrorCodes.ChannelNotCached));
async edit(options) {
if (!this.channel) throw new DiscordjsError(ErrorCodes.ChannelNotCached);
return this.channel.messages.edit(this, options);
}
@@ -840,8 +845,8 @@ class Message extends Base {
* .catch(console.error);
* }
*/
crosspost() {
if (!this.channel) return Promise.reject(new DiscordjsError(ErrorCodes.ChannelNotCached));
async crosspost() {
if (!this.channel) throw new DiscordjsError(ErrorCodes.ChannelNotCached);
return this.channel.messages.crosspost(this.id);
}
@@ -939,8 +944,8 @@ class Message extends Base {
* .then(() => console.log(`Replied to message "${message.content}"`))
* .catch(console.error);
*/
reply(options) {
if (!this.channel) return Promise.reject(new DiscordjsError(ErrorCodes.ChannelNotCached));
async reply(options) {
if (!this.channel) throw new DiscordjsError(ErrorCodes.ChannelNotCached);
let data;
if (options instanceof MessagePayload) {
@@ -956,6 +961,24 @@ class Message extends Base {
return this.channel.send(data);
}
/**
* Forwards this message
*
* @param {TextBasedChannelResolvable} channel The channel to forward this message to.
* @returns {Promise<Message>}
*/
forward(channel) {
const resolvedChannel = this.client.channels.resolve(channel);
if (!resolvedChannel) throw new DiscordjsError(ErrorCodes.InvalidType, 'channel', 'TextBasedChannelResolvable');
return resolvedChannel.send({
forward: {
message: this.id,
channel: this.channelId,
guild: this.guildId,
},
});
}
/**
* Options for starting a thread on a message.
* @typedef {Object} StartThreadOptions
@@ -972,12 +995,12 @@ class Message extends Base {
* @param {StartThreadOptions} [options] Options for starting a thread on this message
* @returns {Promise<ThreadChannel>}
*/
startThread(options = {}) {
if (!this.channel) return Promise.reject(new DiscordjsError(ErrorCodes.ChannelNotCached));
async startThread(options = {}) {
if (!this.channel) throw new DiscordjsError(ErrorCodes.ChannelNotCached);
if (![ChannelType.GuildText, ChannelType.GuildAnnouncement].includes(this.channel.type)) {
return Promise.reject(new DiscordjsError(ErrorCodes.MessageThreadParent));
throw new DiscordjsError(ErrorCodes.MessageThreadParent);
}
if (this.hasThread) return Promise.reject(new DiscordjsError(ErrorCodes.MessageExistingThread));
if (this.hasThread) throw new DiscordjsError(ErrorCodes.MessageExistingThread);
return this.channel.threads.create({ ...options, startMessage: this });
}
@@ -986,8 +1009,8 @@ class Message extends Base {
* @param {boolean} [force=true] Whether to skip the cache check and request the API
* @returns {Promise<Message>}
*/
fetch(force = true) {
if (!this.channel) return Promise.reject(new DiscordjsError(ErrorCodes.ChannelNotCached));
async fetch(force = true) {
if (!this.channel) throw new DiscordjsError(ErrorCodes.ChannelNotCached);
return this.channel.messages.fetch({ message: this.id, force });
}
@@ -995,9 +1018,9 @@ class Message extends Base {
* Fetches the webhook used to create this message.
* @returns {Promise<?Webhook>}
*/
fetchWebhook() {
if (!this.webhookId) return Promise.reject(new DiscordjsError(ErrorCodes.WebhookMessage));
if (this.webhookId === this.applicationId) return Promise.reject(new DiscordjsError(ErrorCodes.WebhookApplication));
async fetchWebhook() {
if (!this.webhookId) throw new DiscordjsError(ErrorCodes.WebhookMessage);
if (this.webhookId === this.applicationId) throw new DiscordjsError(ErrorCodes.WebhookApplication);
return this.client.fetchWebhook(this.webhookId);
}

View File

@@ -3,7 +3,7 @@
const { Buffer } = require('node:buffer');
const { lazy, isJSONEncodable } = require('@discordjs/util');
const { DiscordSnowflake } = require('@sapphire/snowflake');
const { MessageFlags } = require('discord-api-types/v10');
const { MessageFlags, MessageReferenceType } = require('discord-api-types/v10');
const ActionRowBuilder = require('./ActionRowBuilder');
const { DiscordjsError, DiscordjsRangeError, ErrorCodes } = require('../errors');
const { resolveFile } = require('../util/DataResolver');
@@ -199,6 +199,22 @@ class MessagePayload {
}
}
if (typeof this.options.forward === 'object') {
const reference = this.options.forward.message;
const channel_id = reference.channelId ?? this.target.client.channels.resolveId(this.options.forward.channel);
const guild_id = reference.guildId ?? this.target.client.guilds.resolveId(this.options.forward.guild);
const message_id = this.target.messages.resolveId(reference);
if (message_id) {
if (!channel_id) throw new DiscordjsError(ErrorCodes.InvalidType, 'channelId', 'TextBasedChannelResolvable');
message_reference = {
type: MessageReferenceType.Forward,
message_id,
channel_id,
guild_id: guild_id ?? undefined,
};
}
}
const attachments = this.options.files?.map((file, index) => ({
id: index.toString(),
description: file.description,

View File

@@ -1,12 +1,14 @@
'use strict';
const { BaseChannel } = require('./BaseChannel');
const TextBasedChannel = require('./interfaces/TextBasedChannel');
const { DiscordjsError, ErrorCodes } = require('../errors');
const PartialGroupDMMessageManager = require('../managers/PartialGroupDMMessageManager');
/**
* Represents a Partial Group DM Channel on Discord.
* @extends {BaseChannel}
* @implements {TextBasedChannel}
*/
class PartialGroupDMChannel extends BaseChannel {
constructor(client, data) {
@@ -44,6 +46,36 @@ class PartialGroupDMChannel extends BaseChannel {
* @type {PartialGroupDMMessageManager}
*/
this.messages = new PartialGroupDMMessageManager(this);
if ('owner_id' in data) {
/**
* The user id of the owner of this Group DM Channel
* @type {?Snowflake}
*/
this.ownerId = data.owner_id;
} else {
this.ownerId ??= null;
}
if ('last_message_id' in data) {
/**
* The channel's last message id, if one was sent
* @type {?Snowflake}
*/
this.lastMessageId = data.last_message_id;
} else {
this.lastMessageId ??= null;
}
if ('last_pin_timestamp' in data) {
/**
* The timestamp when the last pinned message was pinned, if there was one
* @type {?number}
*/
this.lastPinTimestamp = data.last_pin_timestamp ? Date.parse(data.last_pin_timestamp) : null;
} else {
this.lastPinTimestamp ??= null;
}
}
/**
@@ -55,13 +87,45 @@ class PartialGroupDMChannel extends BaseChannel {
return this.icon && this.client.rest.cdn.channelIcon(this.id, this.icon, options);
}
delete() {
return Promise.reject(new DiscordjsError(ErrorCodes.DeleteGroupDMChannel));
/**
* Fetches the owner of this Group DM Channel.
* @param {BaseFetchOptions} [options] The options for fetching the user
* @returns {Promise<User>}
*/
async fetchOwner(options) {
if (!this.ownerId) {
throw new DiscordjsError(ErrorCodes.FetchOwnerId, 'group DM');
}
return this.client.users.fetch(this.ownerId, options);
}
fetch() {
return Promise.reject(new DiscordjsError(ErrorCodes.FetchGroupDMChannel));
async delete() {
throw new DiscordjsError(ErrorCodes.DeleteGroupDMChannel);
}
async fetch() {
throw new DiscordjsError(ErrorCodes.FetchGroupDMChannel);
}
// These are here only for documentation purposes - they are implemented by TextBasedChannel
/* eslint-disable no-empty-function */
get lastMessage() {}
get lastPinAt() {}
createMessageComponentCollector() {}
awaitMessageComponent() {}
}
TextBasedChannel.applyToClass(PartialGroupDMChannel, true, [
'bulkDelete',
'send',
'sendTyping',
'createMessageCollector',
'awaitMessages',
'fetchWebhooks',
'createWebhook',
'setRateLimitPerUser',
'setNSFW',
]);
module.exports = PartialGroupDMChannel;

View File

@@ -180,8 +180,11 @@ class PermissionOverwrites extends Base {
};
}
const userOrRole = guild.roles.cache.get(overwrite.id) ?? guild.client.users.cache.get(overwrite.id);
if (!userOrRole) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'parameter', 'User nor a Role');
const userOrRole = guild.roles.resolve(overwrite.id) ?? guild.client.users.resolve(overwrite.id);
if (!userOrRole) {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'parameter', 'cached User or Role');
}
const type = userOrRole instanceof Role ? OverwriteType.Role : OverwriteType.Member;
return {

View File

@@ -97,9 +97,9 @@ class Poll extends Base {
* Ends this poll.
* @returns {Promise<Message>}
*/
end() {
async end() {
if (Date.now() > this.expiresTimestamp) {
return Promise.reject(new DiscordjsError(ErrorCodes.PollAlreadyExpired));
throw new DiscordjsError(ErrorCodes.PollAlreadyExpired);
}
return this.message.channel.messages.endPoll(this.message.id);

View File

@@ -182,8 +182,8 @@ class Sticker extends Base {
* Fetches the pack that contains this sticker.
* @returns {Promise<?StickerPack>} The sticker pack or `null` if this sticker does not belong to one.
*/
fetchPack() {
if (!this.packId) return Promise.resolve(null);
async fetchPack() {
if (!this.packId) return null;
return this.client.fetchStickerPacks({ packId: this.packId });
}

View File

@@ -56,6 +56,14 @@ class Subscription extends Base {
*/
this.status = data.status;
if ('renewal_sku_ids' in data) {
/**
* The SKU ids that this user will be subscribed to at renewal
* @type {?Snowflake[]}
*/
this.renewalSkuIds = data.renewal_sku_ids;
}
if ('canceled_at' in data) {
/**
* The timestamp of when the subscription was canceled

View File

@@ -317,7 +317,6 @@ class ThreadChannel extends BaseChannel {
* @param {BaseFetchOptions} [options] Additional options for this fetch
* @returns {Promise<?Message<true>>}
*/
// eslint-disable-next-line require-await
async fetchStarterMessage(options) {
const channel = this.parent instanceof getThreadOnlyChannel() ? this : this.parent;
return channel?.messages.fetch({ message: this.id, ...options }) ?? null;
@@ -407,9 +406,9 @@ class ThreadChannel extends BaseChannel {
* @param {string} [reason] Reason for changing invite
* @returns {Promise<ThreadChannel>}
*/
setInvitable(invitable = true, reason) {
async setInvitable(invitable = true, reason) {
if (this.type !== ChannelType.PrivateThread) {
return Promise.reject(new DiscordjsRangeError(ErrorCodes.ThreadInvitableType, this.type));
throw new DiscordjsRangeError(ErrorCodes.ThreadInvitableType, this.type);
}
return this.edit({ invitable, reason });
}

View File

@@ -141,8 +141,7 @@ class Webhook {
/**
* Options that can be passed into editMessage.
* @typedef {BaseMessageOptions} WebhookMessageEditOptions
* @property {Attachment[]} [attachments] Attachments to send with the message
* @typedef {MessageEditOptions} WebhookMessageEditOptions
* @property {Snowflake} [threadId] The id of the thread this message belongs to
* <info>For interaction webhooks, this property is ignored</info>
*/

View File

@@ -50,6 +50,56 @@ class Application extends Base {
} else {
this.icon ??= null;
}
if ('terms_of_service_url' in data) {
/**
* The URL of the application's terms of service
* @type {?string}
*/
this.termsOfServiceURL = data.terms_of_service_url;
} else {
this.termsOfServiceURL ??= null;
}
if ('privacy_policy_url' in data) {
/**
* The URL of the application's privacy policy
* @type {?string}
*/
this.privacyPolicyURL = data.privacy_policy_url;
} else {
this.privacyPolicyURL ??= null;
}
if ('rpc_origins' in data) {
/**
* The application's RPC origins, if enabled
* @type {string[]}
*/
this.rpcOrigins = data.rpc_origins;
} else {
this.rpcOrigins ??= [];
}
if ('cover_image' in data) {
/**
* The hash of the application's cover image
* @type {?string}
*/
this.cover = data.cover_image;
} else {
this.cover ??= null;
}
if ('verify_key' in data) {
/**
* The hex-encoded key for verification in interactions and the GameSDK's GetTicket
* @type {?string}
*/
this.verifyKey = data.verify_key;
} else {
this.verifyKey ??= null;
}
}
/**

View File

@@ -163,7 +163,7 @@ class InteractionResponses {
if (this.deferred || this.replied) throw new DiscordjsError(ErrorCodes.InteractionAlreadyReplied);
if (typeof options !== 'string') {
if ('fetchReply' in options) {
if ('ephemeral' in options) {
if (!deprecationEmittedForEphemeralOption) {
process.emitWarning(
`Supplying "ephemeral" for interaction response options is deprecated. Utilize flags instead.`,
@@ -272,9 +272,11 @@ class InteractionResponses {
* @param {string|MessagePayload|InteractionReplyOptions} options The options for the reply
* @returns {Promise<Message>}
*/
followUp(options) {
if (!this.deferred && !this.replied) return Promise.reject(new DiscordjsError(ErrorCodes.InteractionNotReplied));
return this.webhook.send(options);
async followUp(options) {
if (!this.deferred && !this.replied) throw new DiscordjsError(ErrorCodes.InteractionNotReplied);
const msg = await this.webhook.send(options);
this.replied = true;
return msg;
}
/**
@@ -425,7 +427,7 @@ class InteractionResponses {
* .then(interaction => console.log(`${interaction.customId} was submitted!`))
* .catch(console.error);
*/
awaitModalSubmit(options) {
async awaitModalSubmit(options) {
if (typeof options.time !== 'number') throw new DiscordjsError(ErrorCodes.InvalidType, 'time', 'number');
const _options = { ...options, max: 1, interactionType: InteractionType.ModalSubmit };
return new Promise((resolve, reject) => {

View File

@@ -75,7 +75,7 @@ class TextBasedChannel {
* @property {?string} [content=''] The content for the message. This can only be `null` when editing a message.
* @property {Array<(EmbedBuilder|Embed|APIEmbed)>} [embeds] The embeds for the message
* @property {MessageMentionOptions} [allowedMentions] Which mentions should be parsed from the message content
* (see [here](https://discord.com/developers/docs/resources/message#allowed-mentions-object) for more details)
* (see {@link https://discord.com/developers/docs/resources/message#allowed-mentions-object here} for more details)
* @property {Array<(AttachmentBuilder|Attachment|AttachmentPayload|BufferResolvable)>} [files]
* The files to send with the message.
* @property {Array<(ActionRowBuilder|ActionRow|APIActionRowComponent)>} [components]
@@ -110,10 +110,18 @@ class TextBasedChannel {
* <info>Only `MessageFlags.SuppressEmbeds` and `MessageFlags.SuppressNotifications` can be set.</info>
*/
/**
* @typedef {Object} ForwardOptions
* @property {MessageResolvable} message The originating message
* @property {TextBasedChannelResolvable} [channel] The channel of the originating message
* @property {GuildResolvable} [guild] The guild of the originating message
*/
/**
* The options for sending a message.
* @typedef {BaseMessageCreateOptions} MessageCreateOptions
* @property {ReplyOptions} [reply] The options for replying to a message
* @property {ForwardOptions} [forward] The options for forwarding a message
*/
/**

View File

@@ -105,6 +105,11 @@
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/interface/APIGuildScheduledEventRecurrenceRule}
*/
/**
* @external APIIncidentsData
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/interface/APIIncidentsData}
*/
/**
* @external APIInteraction
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10#APIInteraction}

View File

@@ -1,8 +1,8 @@
'use strict';
// This file contains the typedefs for camel-cased JSON data
const { ComponentBuilder } = require('@discordjs/builders');
const { ComponentType } = require('discord-api-types/v10');
/**
* @typedef {Object} BaseComponentData
* @property {ComponentType} type The type of component
@@ -71,6 +71,7 @@ const { ComponentType } = require('discord-api-types/v10');
* Transforms API data into a component
* @param {APIMessageComponent|Component} data The data to create the component from
* @returns {Component}
* @ignore
*/
function createComponent(data) {
if (data instanceof Component) {
@@ -103,6 +104,7 @@ function createComponent(data) {
* Transforms API data into a component builder
* @param {APIMessageComponent|ComponentBuilder} data The data to create the component from
* @returns {ComponentBuilder}
* @ignore
*/
function createComponentBuilder(data) {
if (data instanceof ComponentBuilder) {

View File

@@ -30,7 +30,7 @@ const { version } = require('../../package.json');
* @property {MessageMentionOptions} [allowedMentions] The default value for {@link BaseMessageOptions#allowedMentions}
* @property {Partials[]} [partials] Structures allowed to be partial. This means events can be emitted even when
* they're missing all the data for a particular structure. See the "Partial Structures" topic on the
* [guide](https://discordjs.guide/popular-topics/partials.html) for some
* {@link https://discordjs.guide/popular-topics/partials.html guide} for some
* important usage information, as partials require you to put checks in place when handling data.
* @property {boolean} [failIfNotExists=true] The default value for {@link MessageReplyOptions#failIfNotExists}
* @property {PresenceData} [presence={}] Presence data to use upon login
@@ -41,7 +41,7 @@ const { version } = require('../../package.json');
* @property {WebsocketOptions} [ws] Options for the WebSocket
* @property {RESTOptions} [rest] Options for the REST manager
* @property {Function} [jsonTransformer] A function used to transform outgoing json data
* @property {boolean} [enforceNonce=false] The default value for {@link MessageReplyOptions#enforceNonce}
* @property {boolean} [enforceNonce=false] The default value for {@link MessageCreateOptions#enforceNonce}
*/
/**

View File

@@ -63,16 +63,27 @@ function _transformAPIMessageInteractionMetadata(client, messageInteractionMetad
function _transformGuildScheduledEventRecurrenceRule(recurrenceRule) {
return {
start: new Date(recurrenceRule.startAt).toISOString(),
// eslint-disable-next-line eqeqeq
end: recurrenceRule.endAt != null ? new Date(recurrenceRule.endAt).toISOString() : recurrenceRule.endAt,
frequency: recurrenceRule.frequency,
interval: recurrenceRule.interval,
by_weekday: recurrenceRule.byWeekday,
by_n_weekday: recurrenceRule.byNWeekday,
by_month: recurrenceRule.byMonth,
by_month_day: recurrenceRule.byMonthDay,
by_year_day: recurrenceRule.byYearDay,
count: recurrenceRule.count,
};
}
/**
* Transforms API incidents data to a camel-cased variant.
* @param {APIIncidentsData} data The incidents data to transform
* @returns {IncidentActions}
* @ignore
*/
function _transformAPIIncidentsData(data) {
return {
invitesDisabledUntil: data.invites_disabled_until ? new Date(data.invites_disabled_until) : null,
dmsDisabledUntil: data.dms_disabled_until ? new Date(data.dms_disabled_until) : null,
dmSpamDetectedAt: data.dm_spam_detected_at ? new Date(data.dm_spam_detected_at) : null,
raidDetectedAt: data.raid_detected_at ? new Date(data.raid_detected_at) : null,
};
}
@@ -81,4 +92,5 @@ module.exports = {
_transformAPIAutoModerationAction,
_transformAPIMessageInteractionMetadata,
_transformGuildScheduledEventRecurrenceRule,
_transformAPIIncidentsData,
};

View File

@@ -13,7 +13,6 @@ import {
ModalActionRowComponentBuilder,
ModalBuilder as BuildersModal,
AnyComponentBuilder,
ComponentBuilder,
type RestOrArray,
ApplicationCommandOptionAllowedChannelTypes,
} from '@discordjs/builders';
@@ -441,6 +440,11 @@ export abstract class Application extends Base {
public icon: string | null;
public id: Snowflake;
public name: string | null;
public termsOfServiceURL: string | null;
public privacyPolicyURL: string | null;
public rpcOrigins: string[];
public cover: string | null;
public verifyKey: string | null;
public coverURL(options?: ImageURLOptions): string | null;
public iconURL(options?: ImageURLOptions): string | null;
public toJSON(): unknown;
@@ -1120,7 +1124,6 @@ export class ClientApplication extends Application {
public subscriptions: SubscriptionManager;
public guildId: Snowflake | null;
public get guild(): Guild | null;
public cover: string | null;
public flags: Readonly<ApplicationFlagsBitField>;
public approximateGuildCount: number | null;
public approximateUserInstallCount: number | null;
@@ -1135,7 +1138,6 @@ export class ClientApplication extends Application {
public eventWebhooksStatus: ApplicationWebhookEventStatus | null;
public eventWebhooksTypes: ApplicationWebhookEventType[] | null;
public roleConnectionsVerificationURL: string | null;
public rpcOrigins: string[];
public edit(options: ClientApplicationEditOptions): Promise<ClientApplication>;
public fetch(): Promise<ClientApplication>;
public fetchRoleConnectionMetadataRecords(): Promise<ApplicationRoleConnectionMetadata[]>;
@@ -1367,16 +1369,10 @@ export class ContextMenuCommandInteraction<Cached extends CacheType = CacheType>
private resolveContextMenuOptions(data: APIApplicationCommandInteractionData): CommandInteractionOption<Cached>[];
}
/** @internal */
export interface ResolvedFile {
data: Buffer;
contentType?: string;
}
// tslint:disable-next-line no-empty-interface
export interface DMChannel
extends Omit<
TextBasedChannelFields<false>,
TextBasedChannelFields<false, true>,
'bulkDelete' | 'fetchWebhooks' | 'createWebhook' | 'setRateLimitPerUser' | 'setNSFW'
> {}
export class DMChannel extends BaseChannel {
@@ -1514,6 +1510,7 @@ export class Guild extends AnonymousGuild {
public shardId: number;
public stageInstances: StageInstanceManager;
public stickers: GuildStickerManager;
public incidentsData: IncidentActions | null;
public get systemChannel(): TextChannel | null;
public systemChannelFlags: Readonly<SystemChannelFlagsBitField>;
public systemChannelId: Snowflake | null;
@@ -1547,6 +1544,7 @@ export class Guild extends AnonymousGuild {
public widgetImageURL(style?: GuildWidgetStyle): string;
public leave(): Promise<Guild>;
public disableInvites(disabled?: boolean): Promise<Guild>;
public setIncidentActions(incidentActions: IncidentActionsEditOptions): Promise<IncidentActions>;
public setAFKChannel(afkChannel: VoiceChannelResolvable | null, reason?: string): Promise<Guild>;
public setAFKTimeout(afkTimeout: number, reason?: string): Promise<Guild>;
public setBanner(banner: BufferResolvable | Base64Resolvable | null, reason?: string): Promise<Guild>;
@@ -2312,6 +2310,7 @@ export class Message<InGuild extends boolean = boolean> extends Base {
public reply(
options: string | MessagePayload | MessageReplyOptions,
): Promise<OmitPartialGroupDMChannel<Message<InGuild>>>;
public forward(channel: Exclude<TextBasedChannelResolvable, PartialGroupDMChannel>): Promise<Message>;
public resolveComponent(customId: string): MessageActionRowComponent | null;
public startThread(options: StartThreadOptions): Promise<PublicThreadChannel<false>>;
public suppressEmbeds(suppress?: boolean): Promise<OmitPartialGroupDMChannel<Message<InGuild>>>;
@@ -2697,6 +2696,19 @@ export class OAuth2Guild extends BaseGuild {
public permissions: Readonly<PermissionsBitField>;
}
export interface PartialGroupDMChannel
extends Omit<
TextBasedChannelFields<false, false>,
| 'bulkDelete'
| 'send'
| 'sendTyping'
| 'createMessageCollector'
| 'awaitMessages'
| 'fetchWebhooks'
| 'createWebhook'
| 'setRateLimitPerUser'
| 'setNSFW'
> {}
export class PartialGroupDMChannel extends BaseChannel {
private constructor(client: Client<true>, data: RawPartialGroupDMChannelData);
public type: ChannelType.GroupDM;
@@ -2704,8 +2716,9 @@ export class PartialGroupDMChannel extends BaseChannel {
public name: string | null;
public icon: string | null;
public recipients: PartialRecipient[];
public messages: PartialGroupDMMessageManager;
public ownerId: Snowflake | null;
public iconURL(options?: ImageURLOptions): string | null;
public fetchOwner(options?: BaseFetchOptions): Promise<User>;
public toString(): ChannelMention;
}
@@ -2742,6 +2755,7 @@ export interface ThreadOnlyChannel
| 'awaitMessages'
| 'createMessageComponentCollector'
| 'awaitMessageComponent'
| 'messages'
> {}
export abstract class ThreadOnlyChannel extends GuildChannel {
public type: ChannelType.GuildForum | ChannelType.GuildMedia;
@@ -3241,6 +3255,7 @@ export class Subscription extends Base {
public userId: Snowflake;
public skuIds: Snowflake[];
public entitlementIds: Snowflake[];
public renewalSkuIds: Snowflake[] | null;
public currentPeriodStartTimestamp: number;
public currentPeriodEndTimestamp: number;
public status: SubscriptionStatus;
@@ -3683,28 +3698,6 @@ export function transformResolved<Cached extends CacheType>(
): CommandInteractionResolvedData<Cached>;
export function resolveSKUId(resolvable: SKUResolvable): Snowflake | null;
export interface MappedComponentBuilderTypes {
[ComponentType.Button]: ButtonBuilder;
[ComponentType.StringSelect]: StringSelectMenuBuilder;
[ComponentType.UserSelect]: UserSelectMenuBuilder;
[ComponentType.RoleSelect]: RoleSelectMenuBuilder;
[ComponentType.MentionableSelect]: MentionableSelectMenuBuilder;
[ComponentType.ChannelSelect]: ChannelSelectMenuBuilder;
[ComponentType.ActionRow]: ActionRowBuilder;
[ComponentType.TextInput]: TextInputBuilder;
}
export interface MappedComponentTypes {
[ComponentType.Button]: ButtonComponent;
[ComponentType.StringSelect]: StringSelectMenuComponent;
[ComponentType.UserSelect]: UserSelectMenuComponent;
[ComponentType.RoleSelect]: RoleSelectMenuComponent;
[ComponentType.MentionableSelect]: MentionableSelectMenuComponent;
[ComponentType.ChannelSelect]: ChannelSelectMenuComponent;
[ComponentType.ActionRow]: ActionRowComponent;
[ComponentType.TextInput]: TextInputComponent;
}
/** @internal */
export interface CreateChannelOptions {
allowFromUnknownGuild?: boolean;
@@ -3718,17 +3711,6 @@ export function createChannel(
extras?: CreateChannelOptions,
): Channel;
export function createComponent<Type extends keyof MappedComponentTypes>(
data: APIMessageComponent & { type: Type },
): MappedComponentTypes[Type];
export function createComponent<Data extends Component>(data: Data): Data;
export function createComponent(data: APIMessageComponent | Component): Component;
export function createComponentBuilder<Type extends keyof MappedComponentBuilderTypes>(
data: APIMessageComponent & { type: Type },
): MappedComponentBuilderTypes[Type];
export function createComponentBuilder<Data extends ComponentBuilder>(data: Data): Data;
export function createComponentBuilder(data: APIMessageComponent | ComponentBuilder): ComponentBuilder;
/** @deprecated This class is redundant as all methods of the class can be imported from discord.js directly. */
export class Formatters extends null {
/** @deprecated Import this method directly from discord.js instead. */
@@ -3767,19 +3749,6 @@ export class Formatters extends null {
public static userMention: typeof userMention;
}
/** @internal */
export function resolveBase64(data: Base64Resolvable): string;
/** @internal */
export function resolveCode(data: string, regex: RegExp): string;
/** @internal */
export function resolveFile(resource: BufferResolvable | Stream): Promise<ResolvedFile>;
/** @internal */
export function resolveImage(resource: BufferResolvable | Base64Resolvable): Promise<string | null>;
/** @internal */
export function resolveInviteCode(data: InviteResolvable): string;
/** @internal */
export function resolveGuildTemplateCode(data: GuildTemplateResolvable): string;
export type ComponentData =
| MessageActionRowComponentData
| ModalActionRowComponentData
@@ -4576,6 +4545,10 @@ export class GuildManager extends CachedManager<Snowflake, Guild, GuildResolvabl
public create(options: GuildCreateOptions): Promise<Guild>;
public fetch(options: Snowflake | FetchGuildOptions): Promise<Guild>;
public fetch(options?: FetchGuildsOptions): Promise<Collection<Snowflake, OAuth2Guild>>;
public setIncidentActions(
guild: GuildResolvable,
incidentActions: IncidentActionsEditOptions,
): Promise<IncidentActions>;
public widgetImageURL(guild: GuildResolvable, style?: GuildWidgetStyle): string;
}
@@ -4906,13 +4879,13 @@ export interface PartialTextBasedChannelFields<InGuild extends boolean = boolean
send(options: string | MessagePayload | MessageCreateOptions): Promise<Message<InGuild>>;
}
export interface TextBasedChannelFields<InGuild extends boolean = boolean>
export interface TextBasedChannelFields<InGuild extends boolean = boolean, InDM extends boolean = boolean>
extends PartialTextBasedChannelFields<InGuild> {
lastMessageId: Snowflake | null;
get lastMessage(): Message | null;
lastPinTimestamp: number | null;
get lastPinAt(): Date | null;
messages: If<InGuild, GuildMessageManager, DMMessageManager>;
messages: If<InGuild, GuildMessageManager, If<InDM, DMMessageManager, PartialGroupDMMessageManager>>;
awaitMessageComponent<ComponentType extends MessageComponentType>(
options?: AwaitMessageCollectorOptionsParams<ComponentType, true>,
): Promise<MappedInteractionTypes[ComponentType]>;
@@ -6203,7 +6176,7 @@ export type GuildAuditLogsResolvable = AuditLogEvent | null;
export type GuildAuditLogsTargetType = GuildAuditLogsTypes[keyof GuildAuditLogsTypes][0] | 'All' | 'Unknown';
export type GuildAuditLogsTargets = {
[key in GuildAuditLogsTargetType]: GuildAuditLogsTargetType;
[Key in GuildAuditLogsTargetType]: GuildAuditLogsTargetType;
};
export type GuildBanResolvable = GuildBan | UserResolvable;
@@ -6406,18 +6379,35 @@ export interface GuildScheduledEventCreateOptions {
recurrenceRule?: GuildScheduledEventRecurrenceRuleOptions;
}
export interface GuildScheduledEventRecurrenceRuleOptions {
export type GuildScheduledEventRecurrenceRuleOptions =
| BaseGuildScheduledEventRecurrenceRuleOptions<
GuildScheduledEventRecurrenceRuleFrequency.Yearly,
{
byMonth: readonly GuildScheduledEventRecurrenceRuleMonth[];
byMonthDay: readonly number[];
}
>
| BaseGuildScheduledEventRecurrenceRuleOptions<
GuildScheduledEventRecurrenceRuleFrequency.Monthly,
{
byNWeekday: readonly GuildScheduledEventRecurrenceRuleNWeekday[];
}
>
| BaseGuildScheduledEventRecurrenceRuleOptions<
GuildScheduledEventRecurrenceRuleFrequency.Weekly | GuildScheduledEventRecurrenceRuleFrequency.Daily,
{
byWeekday: readonly GuildScheduledEventRecurrenceRuleWeekday[];
}
>;
type BaseGuildScheduledEventRecurrenceRuleOptions<
Frequency extends GuildScheduledEventRecurrenceRuleFrequency,
Extra extends {},
> = {
startAt: DateResolvable;
endAt: DateResolvable;
frequency: GuildScheduledEventRecurrenceRuleFrequency;
interval: number;
byWeekday: readonly GuildScheduledEventRecurrenceRuleWeekday[];
byNWeekday: readonly GuildScheduledEventRecurrenceRuleNWeekday[];
byMonth: readonly GuildScheduledEventRecurrenceRuleMonth[];
byMonthDay: readonly number[];
byYearDay: readonly number[];
count: number;
}
frequency: Frequency;
} & Extra;
export interface GuildScheduledEventEditOptions<
Status extends GuildScheduledEventStatus,
@@ -6496,6 +6486,18 @@ export interface GuildOnboardingPromptOptionData {
export type HexColorString = `#${string}`;
export interface IncidentActions {
invitesDisabledUntil: Date | null;
dmsDisabledUntil: Date | null;
dmSpamDetectedAt: Date | null;
raidDetectedAt: Date | null;
}
export interface IncidentActionsEditOptions {
invitesDisabledUntil?: DateResolvable | null | undefined;
dmsDisabledUntil?: DateResolvable | null | undefined;
}
export interface IntegrationAccount {
id: string | Snowflake;
name: string;
@@ -6540,10 +6542,7 @@ export interface InteractionCollectorOptions<
export interface InteractionDeferReplyOptions {
/** @deprecated Use {@link InteractionDeferReplyOptions.flags} instead. */
ephemeral?: boolean;
flags?: BitFieldResolvable<
Extract<MessageFlagsString, 'Ephemeral' | 'SuppressEmbeds' | 'SuppressNotifications'>,
MessageFlags.Ephemeral | MessageFlags.SuppressEmbeds | MessageFlags.SuppressNotifications
>;
flags?: BitFieldResolvable<Extract<MessageFlagsString, 'Ephemeral'>, MessageFlags.Ephemeral> | undefined;
withResponse?: boolean;
/** @deprecated Use {@link InteractionDeferReplyOptions.withResponse} instead. */
fetchReply?: boolean;
@@ -6562,10 +6561,12 @@ export interface InteractionReplyOptions extends BaseMessageOptionsWithPoll {
withResponse?: boolean;
/** @deprecated Use {@link InteractionReplyOptions.withResponse} instead. */
fetchReply?: boolean;
flags?: BitFieldResolvable<
Extract<MessageFlagsString, 'Ephemeral' | 'SuppressEmbeds' | 'SuppressNotifications'>,
MessageFlags.Ephemeral | MessageFlags.SuppressEmbeds | MessageFlags.SuppressNotifications
>;
flags?:
| BitFieldResolvable<
Extract<MessageFlagsString, 'Ephemeral' | 'SuppressEmbeds' | 'SuppressNotifications'>,
MessageFlags.Ephemeral | MessageFlags.SuppressEmbeds | MessageFlags.SuppressNotifications
>
| undefined;
}
export interface InteractionUpdateOptions extends MessageEditOptions {
@@ -6759,11 +6760,14 @@ export interface MessageCreateOptions extends BaseMessageOptionsWithPoll {
nonce?: string | number;
enforceNonce?: boolean;
reply?: ReplyOptions;
forward?: ForwardOptions;
stickers?: readonly StickerResolvable[];
flags?: BitFieldResolvable<
Extract<MessageFlagsString, 'SuppressEmbeds' | 'SuppressNotifications'>,
MessageFlags.SuppressEmbeds | MessageFlags.SuppressNotifications
>;
flags?:
| BitFieldResolvable<
Extract<MessageFlagsString, 'SuppressEmbeds' | 'SuppressNotifications'>,
MessageFlags.SuppressEmbeds | MessageFlags.SuppressNotifications
>
| undefined;
}
export interface GuildForumThreadMessageCreateOptions
@@ -6777,7 +6781,7 @@ export interface MessageEditAttachmentData {
export interface MessageEditOptions extends Omit<BaseMessageOptions, 'content'> {
content?: string | null;
attachments?: readonly (Attachment | MessageEditAttachmentData)[];
flags?: BitFieldResolvable<Extract<MessageFlagsString, 'SuppressEmbeds'>, MessageFlags.SuppressEmbeds>;
flags?: BitFieldResolvable<Extract<MessageFlagsString, 'SuppressEmbeds'>, MessageFlags.SuppressEmbeds> | undefined;
}
export type MessageReactionResolvable = MessageReaction | Snowflake | string;
@@ -7009,7 +7013,21 @@ export interface ReplyOptions {
failIfNotExists?: boolean;
}
export interface MessageReplyOptions extends Omit<MessageCreateOptions, 'reply'> {
export interface BaseForwardOptions {
message: MessageResolvable;
channel?: Exclude<TextBasedChannelResolvable, PartialGroupDMChannel>;
guild?: GuildResolvable;
}
export type ForwardOptionsWithMandatoryChannel = BaseForwardOptions & Required<Pick<BaseForwardOptions, 'channel'>>;
export interface ForwardOptionsWithOptionalChannel extends BaseForwardOptions {
message: Exclude<MessageResolvable, Snowflake>;
}
export type ForwardOptions = ForwardOptionsWithMandatoryChannel | ForwardOptionsWithOptionalChannel;
export interface MessageReplyOptions extends Omit<MessageCreateOptions, 'reply' | 'forward'> {
failIfNotExists?: boolean;
}
@@ -7274,7 +7292,7 @@ export interface WebhookEditOptions {
reason?: string;
}
export interface WebhookMessageEditOptions extends Omit<MessageEditOptions, 'flags'> {
export interface WebhookMessageEditOptions extends MessageEditOptions {
threadId?: Snowflake;
}
@@ -7288,7 +7306,8 @@ export interface WebhookFetchMessageOptions {
threadId?: Snowflake;
}
export interface WebhookMessageCreateOptions extends Omit<MessageCreateOptions, 'nonce' | 'reply' | 'stickers'> {
export interface WebhookMessageCreateOptions
extends Omit<MessageCreateOptions, 'nonce' | 'reply' | 'stickers' | 'forward'> {
username?: string;
avatarURL?: string;
threadId?: Snowflake;

View File

@@ -33,6 +33,9 @@ import {
APIMentionableSelectComponent,
APIModalInteractionResponseCallbackData,
WebhookType,
GuildScheduledEventRecurrenceRuleFrequency,
GuildScheduledEventRecurrenceRuleMonth,
GuildScheduledEventRecurrenceRuleWeekday,
} from 'discord-api-types/v10';
import {
ApplicationCommand,
@@ -214,6 +217,8 @@ import {
PollData,
UserManager,
InteractionCallbackResponse,
GuildScheduledEventRecurrenceRuleOptions,
ThreadOnlyChannel,
} from '.';
import {
expectAssignable,
@@ -2457,6 +2462,16 @@ declare const partialGroupDMChannel: PartialGroupDMChannel;
declare const categoryChannel: CategoryChannel;
declare const stageChannel: StageChannel;
declare const forumChannel: ForumChannel;
declare const mediaChannel: MediaChannel;
declare const threadOnlyChannel: ThreadOnlyChannel;
// Threads have messages.
expectType<GuildMessageManager>(threadChannel.messages);
// Thread-only channels have threads—not messages.
notPropertyOf(threadOnlyChannel, 'messages');
notPropertyOf(forumChannel, 'messages');
notPropertyOf(mediaChannel, 'messages');
await forumChannel.edit({
availableTags: [...forumChannel.availableTags, { name: 'tag' }],
@@ -2679,3 +2694,89 @@ client.on('interactionCreate', interaction => {
declare const guildScheduledEventManager: GuildScheduledEventManager;
await guildScheduledEventManager.edit(snowflake, { recurrenceRule: null });
{
expectNotAssignable<GuildScheduledEventRecurrenceRuleOptions>({
startAt: new Date(),
frequency: GuildScheduledEventRecurrenceRuleFrequency.Yearly,
interval: 1,
byMonth: [GuildScheduledEventRecurrenceRuleMonth.May],
byMonthDay: [4],
// Invalid property
byWeekday: [GuildScheduledEventRecurrenceRuleWeekday.Monday],
});
expectNotAssignable<GuildScheduledEventRecurrenceRuleOptions>({
startAt: new Date(),
frequency: GuildScheduledEventRecurrenceRuleFrequency.Yearly,
interval: 1,
byMonth: [GuildScheduledEventRecurrenceRuleMonth.May],
byMonthDay: [4],
// Invalid property
byNWeekday: [{ n: 1, day: GuildScheduledEventRecurrenceRuleWeekday.Monday }],
});
expectAssignable<GuildScheduledEventRecurrenceRuleOptions>({
startAt: new Date(),
frequency: GuildScheduledEventRecurrenceRuleFrequency.Yearly,
interval: 1,
byMonth: [GuildScheduledEventRecurrenceRuleMonth.May],
byMonthDay: [4],
});
}
{
expectAssignable<GuildScheduledEventRecurrenceRuleOptions>({
startAt: new Date(),
frequency: GuildScheduledEventRecurrenceRuleFrequency.Monthly,
interval: 1,
byNWeekday: [{ n: 1, day: GuildScheduledEventRecurrenceRuleWeekday.Monday }],
});
expectNotAssignable<GuildScheduledEventRecurrenceRuleOptions>({
startAt: new Date(),
frequency: GuildScheduledEventRecurrenceRuleFrequency.Monthly,
interval: 1,
byNWeekday: [{ n: 1, day: GuildScheduledEventRecurrenceRuleWeekday.Monday }],
// Invalid property
byWeekday: [GuildScheduledEventRecurrenceRuleWeekday.Monday],
});
}
{
expectAssignable<GuildScheduledEventRecurrenceRuleOptions>({
startAt: new Date(),
frequency: GuildScheduledEventRecurrenceRuleFrequency.Weekly,
interval: 1,
byWeekday: [GuildScheduledEventRecurrenceRuleWeekday.Monday],
});
expectNotAssignable<GuildScheduledEventRecurrenceRuleOptions>({
startAt: new Date(),
frequency: GuildScheduledEventRecurrenceRuleFrequency.Weekly,
interval: 1,
byWeekday: [GuildScheduledEventRecurrenceRuleWeekday.Monday],
// Invalid property
byNWeekday: [{ n: 1, day: GuildScheduledEventRecurrenceRuleWeekday.Monday }],
});
}
{
expectNotAssignable<GuildScheduledEventRecurrenceRuleOptions>({
startAt: new Date(),
frequency: GuildScheduledEventRecurrenceRuleFrequency.Daily,
interval: 1,
byWeekday: [GuildScheduledEventRecurrenceRuleWeekday.Monday],
// Invalid property
byNWeekday: [{ n: 1, day: GuildScheduledEventRecurrenceRuleWeekday.Monday }],
});
expectNotAssignable<GuildScheduledEventRecurrenceRuleOptions>({
startAt: new Date(),
frequency: GuildScheduledEventRecurrenceRuleFrequency.Daily,
interval: 1,
byWeekday: [GuildScheduledEventRecurrenceRuleWeekday.Monday],
// Invalid property
byMonth: [GuildScheduledEventRecurrenceRuleMonth.May],
});
}

View File

@@ -9,7 +9,8 @@
<a href="https://www.npmjs.com/package/@discordjs/formatters"><img src="https://img.shields.io/npm/v/@discordjs/formatters.svg?maxAge=3600" alt="npm version" /></a>
<a href="https://www.npmjs.com/package/@discordjs/formatters"><img src="https://img.shields.io/npm/dt/@discordjs/formatters.svg?maxAge=3600" alt="npm downloads" /></a>
<a href="https://github.com/discordjs/discord.js/actions"><img src="https://github.com/discordjs/discord.js/actions/workflows/test.yml/badge.svg" alt="Build status" /></a>
<a href="https://codecov.io/gh/discordjs/discord.js" ><img src="https://codecov.io/gh/discordjs/discord.js/branch/main/graph/badge.svg?precision=2&flag=formatters" alt="Code coverage" /></a>
<a href="https://github.com/discordjs/discord.js/commits/main/packages/formatters"><img alt="Last commit." src="https://img.shields.io/github/last-commit/discordjs/discord.js?logo=github&logoColor=ffffff&path=packages%2Fformatters"></a>
<a href="https://codecov.io/gh/discordjs/discord.js"><img src="https://codecov.io/gh/discordjs/discord.js/branch/main/graph/badge.svg?precision=2&flag=formatters" alt="Code coverage" /></a>
</p>
<p>
<a href="https://vercel.com/?utm_source=discordjs&utm_campaign=oss"><img src="https://raw.githubusercontent.com/discordjs/discord.js/main/.github/powered-by-vercel.svg" alt="Vercel" /></a>

View File

@@ -55,7 +55,7 @@
"homepage": "https://discord.js.org",
"funding": "https://github.com/discordjs/discord.js?sponsor",
"dependencies": {
"discord-api-types": "^0.37.114"
"discord-api-types": "^0.37.119"
},
"devDependencies": {
"@discordjs/api-extractor": "workspace:^",

View File

@@ -7,6 +7,7 @@
<p>
<a href="https://discord.gg/djs"><img src="https://img.shields.io/discord/222078108977594368?color=5865F2&logo=discord&logoColor=white" alt="Discord server" /></a>
<a href="https://github.com/discordjs/discord.js/actions"><img src="https://github.com/discordjs/discord.js/actions/workflows/test.yml/badge.svg" alt="Build status" /></a>
<a href="https://github.com/discordjs/discord.js/commits/main/packages/next"><img alt="Last commit." src="https://img.shields.io/github/last-commit/discordjs/discord.js?logo=github&logoColor=ffffff&path=packages%2Fnext"></a>
</p>
<p>
<a href="https://vercel.com/?utm_source=discordjs&utm_campaign=oss"><img src="https://raw.githubusercontent.com/discordjs/discord.js/main/.github/powered-by-vercel.svg" alt="Vercel" /></a>

View File

@@ -72,7 +72,7 @@
"@discordjs/rest": "workspace:^",
"@discordjs/util": "workspace:^",
"@discordjs/ws": "workspace:^",
"discord-api-types": "^0.37.114"
"discord-api-types": "^0.37.119"
},
"devDependencies": {
"@discordjs/api-extractor": "workspace:^",

View File

@@ -9,7 +9,8 @@
<a href="https://www.npmjs.com/package/@discordjs/proxy"><img src="https://img.shields.io/npm/v/@discordjs/proxy.svg?maxAge=3600" alt="npm version" /></a>
<a href="https://www.npmjs.com/package/@discordjs/proxy"><img src="https://img.shields.io/npm/dt/@discordjs/proxy.svg?maxAge=3600" alt="npm downloads" /></a>
<a href="https://github.com/discordjs/discord.js/actions"><img src="https://github.com/discordjs/discord.js/actions/workflows/test.yml/badge.svg" alt="Build status" /></a>
<a href="https://codecov.io/gh/discordjs/discord.js" ><img src="https://codecov.io/gh/discordjs/discord.js/branch/main/graph/badge.svg?precision=2&flag=proxy" alt="Code coverage" /></a>
<a href="https://github.com/discordjs/discord.js/commits/main/packages/proxy"><img alt="Last commit." src="https://img.shields.io/github/last-commit/discordjs/discord.js?logo=github&logoColor=ffffff&path=packages%2Fproxy"></a>
<a href="https://codecov.io/gh/discordjs/discord.js"><img src="https://codecov.io/gh/discordjs/discord.js/branch/main/graph/badge.svg?precision=2&flag=proxy" alt="Code coverage" /></a>
</p>
<p>
<a href="https://vercel.com/?utm_source=discordjs&utm_campaign=oss"><img src="https://raw.githubusercontent.com/discordjs/discord.js/main/.github/powered-by-vercel.svg" alt="Vercel" /></a>

View File

@@ -68,7 +68,7 @@
"@discordjs/rest": "workspace:^",
"@discordjs/util": "workspace:^",
"tslib": "^2.6.3",
"undici": "6.19.8"
"undici": "6.21.1"
},
"devDependencies": {
"@discordjs/api-extractor": "workspace:^",

View File

@@ -2,6 +2,12 @@
All notable changes to this project will be documented in this file.
# [@discordjs/rest@2.4.2](https://github.com/discordjs/discord.js/compare/@discordjs/rest@2.4.1...@discordjs/rest@2.4.2) - (2025-01-01)
## Bug Fixes
- Correct guild member banner URL ([8d69b24](https://github.com/discordjs/discord.js/commit/8d69b24b5c83249dffa5899a417a9dcbc6f3f30c))
# [@discordjs/rest@2.4.0](https://github.com/discordjs/discord.js/compare/@discordjs/rest@2.3.0...@discordjs/rest@2.4.0) - (2024-09-01)
## Bug Fixes

View File

@@ -9,6 +9,7 @@
<a href="https://www.npmjs.com/package/@discordjs/rest"><img src="https://img.shields.io/npm/v/@discordjs/rest.svg?maxAge=3600" alt="npm version" /></a>
<a href="https://www.npmjs.com/package/@discordjs/rest"><img src="https://img.shields.io/npm/dt/@discordjs/rest.svg?maxAge=3600" alt="npm downloads" /></a>
<a href="https://github.com/discordjs/discord.js/actions"><img src="https://github.com/discordjs/discord.js/actions/workflows/test.yml/badge.svg" alt="Tests status" /></a>
<a href="https://github.com/discordjs/discord.js/commits/main/packages/rest" ><img alt="Last commit." src="https://img.shields.io/github/last-commit/discordjs/discord.js?logo=github&logoColor=ffffff&path=packages%2Frest"></a>
<a href="https://codecov.io/gh/discordjs/discord.js" ><img src="https://codecov.io/gh/discordjs/discord.js/branch/main/graph/badge.svg?precision=2&flag=rest" alt="Code coverage" /></a>
</p>
<p>

View File

@@ -76,6 +76,20 @@ test('guildMemberAvatar dynamic-not-animated', () => {
expect(cdn.guildMemberAvatar(id, id, hash)).toEqual(`${baseCDN}/guilds/${id}/users/${id}/avatars/${hash}.webp`);
});
test('guildMemberBanner default', () => {
expect(cdn.guildMemberBanner(id, id, hash)).toEqual(`${baseCDN}/guilds/${id}/users/${id}/banners/${hash}.webp`);
});
test('guildMemberBanner dynamic-animated', () => {
expect(cdn.guildMemberBanner(id, id, animatedHash)).toEqual(
`${baseCDN}/guilds/${id}/users/${id}/banners/${animatedHash}.gif`,
);
});
test('guildMemberBanner dynamic-not-animated', () => {
expect(cdn.guildMemberBanner(id, id, hash)).toEqual(`${baseCDN}/guilds/${id}/users/${id}/banners/${hash}.webp`);
});
test('guildScheduledEventCover default', () => {
expect(cdn.guildScheduledEventCover(id, hash)).toEqual(`${baseCDN}/guild-events/${id}/${hash}.webp`);
});

View File

@@ -1,7 +1,7 @@
{
"$schema": "https://json.schemastore.org/package.json",
"name": "@discordjs/rest",
"version": "2.4.1",
"version": "2.4.3",
"description": "The REST API for discord.js",
"scripts": {
"test": "vitest run",
@@ -88,10 +88,10 @@
"@sapphire/async-queue": "^1.5.3",
"@sapphire/snowflake": "^3.5.3",
"@vladfrangu/async_event_emitter": "^2.4.6",
"discord-api-types": "^0.37.114",
"discord-api-types": "^0.37.119",
"magic-bytes.js": "^1.10.0",
"tslib": "^2.6.3",
"undici": "6.19.8"
"undici": "6.21.1"
},
"devDependencies": {
"@discordjs/api-extractor": "workspace:^",

View File

@@ -254,7 +254,7 @@ export class CDN {
bannerHash: string,
options?: Readonly<ImageURLOptions>,
): string {
return this.dynamicMakeURL(`/guilds/${guildId}/users/${userId}/banner`, bannerHash, options);
return this.dynamicMakeURL(`/guilds/${guildId}/users/${userId}/banners/${bannerHash}`, bannerHash, options);
}
/**

View File

@@ -68,7 +68,7 @@
"@vercel/postgres": "^0.9.0",
"commander": "^12.1.0",
"tslib": "^2.6.3",
"undici": "6.19.8",
"undici": "6.21.1",
"yaml": "^2.5.0"
},
"devDependencies": {

View File

@@ -0,0 +1,109 @@
export const BuiltinDocumentationLinks = {
// Built-in types
bigint: 'https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/BigInt',
boolean: 'https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean',
null: 'https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/null',
number: 'https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number',
string: 'https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String',
symbol: 'https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Symbol',
undefined: 'https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined',
// Built-in classes
AbortSignal: 'https://developer.mozilla.org/docs/Web/API/AbortSignal',
Agent: 'https://undici.nodejs.org/#/docs/api/Agent',
Array: 'https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array',
ArrayBuffer: 'https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer',
AsyncGenerator: 'https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/AsyncGenerator',
AsyncIterable: 'https://developer.mozilla.org/docs/Web/JavaScript/Reference/Iteration_protocols',
AsyncIterableIterator: 'https://developer.mozilla.org/docs/Web/JavaScript/Reference/Iteration_protocols',
Buffer: 'https://nodejs.org/api/buffer.html#class-buffer',
ChildProcess: 'https://nodejs.org/api/child_process.html#class-childprocess',
Date: 'https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Date',
Dispatcher: 'https://undici.nodejs.org/#/docs/api/Dispatcher',
Error: 'https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Error',
Function: 'https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Function',
Generator: 'https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Generator',
IncomingMessage: 'https://nodejs.org/api/http.html#class-httpincomingmessage',
Iterable: 'https://developer.mozilla.org/docs/Web/JavaScript/Reference/Iteration_protocols',
IterableIterator: 'https://developer.mozilla.org/docs/Web/JavaScript/Reference/Iteration_protocols',
Iterator: 'https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Iterator',
Map: 'https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Map',
MessagePort: 'https://nodejs.org/api/worker_threads.html#class-messageport',
Promise: 'https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise',
RangeError: 'https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/RangeError',
Readable: 'https://nodejs.org/api/stream.html#class-streamreadable',
ReadableStream: 'https://developer.mozilla.org/docs/Web/API/ReadableStream',
RegExp: 'https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/RegExp',
Response: 'https://developer.mozilla.org/docs/Web/API/Response',
ServerResponse: 'https://nodejs.org/api/http.html#class-httpserverresponse',
Set: 'https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Set',
Stream: 'https://nodejs.org/api/stream.html#stream',
SymbolConstructor: 'https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Symbol',
TypeError: 'https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/TypeError',
URL: 'https://developer.mozilla.org/docs/Web/API/URL',
URLSearchParams: 'https://developer.mozilla.org/docs/Web/API/URLSearchParams',
WeakMap: 'https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/WeakMap',
WeakRef: 'https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/WeakRef',
WeakSet: 'https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/WeakSet',
WebSocket: 'https://developer.mozilla.org/docs/Web/API/WebSocket',
Worker: 'https://nodejs.org/api/worker_threads.html#class-worker',
'NodeJS.Timeout': 'https://nodejs.org/api/timers.html#class-timeout',
// Typed arrays
BigInt64Array: 'https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/BigInt64Array',
BigUint64Array: 'https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/BigUint64Array',
Float32Array: 'https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Float32Array',
Float64Array: 'https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Float64Array',
Int16Array: 'https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Int16Array',
Int32Array: 'https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Int32Array',
Int8Array: 'https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Int8Array',
Uint16Array: 'https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint16Array',
Uint32Array: 'https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint32Array',
Uint8Array: 'https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array',
Uint8ClampedArray: 'https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8ClampedArray',
// TypeScript types
any: 'https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#any',
keyof: 'https://www.typescriptlang.org/docs/handbook/2/keyof-types.html',
never: 'https://www.typescriptlang.org/docs/handbook/2/functions.html#never',
object: 'https://www.typescriptlang.org/docs/handbook/2/functions.html#object',
ReadonlyArray: 'https://www.typescriptlang.org/docs/handbook/2/objects.html#the-readonlyarray-type',
ReadonlyMap:
'https://github.com/microsoft/TypeScript/blob/1416053b9e85ca2344a7a6aa10456d633ea1cd65/src/lib/es2015.collection.d.ts#L38-L43',
ReadonlySet:
'https://github.com/microsoft/TypeScript/blob/1416053b9e85ca2344a7a6aa10456d633ea1cd65/src/lib/es2015.collection.d.ts#L104-L108',
unknown: 'https://www.typescriptlang.org/docs/handbook/2/functions.html#unknown',
this: 'https://www.typescriptlang.org/docs/handbook/2/classes.html#this-types',
typeof: 'https://www.typescriptlang.org/docs/handbook/2/typeof-types.html',
void: 'https://www.typescriptlang.org/docs/handbook/2/functions.html#void',
// TypeScript utility types
Awaited: 'https://www.typescriptlang.org/docs/handbook/utility-types.html#awaitedtype',
Partial: 'https://www.typescriptlang.org/docs/handbook/utility-types.html#partialtype',
Required: 'https://www.typescriptlang.org/docs/handbook/utility-types.html#requiredtype',
Readonly: 'https://www.typescriptlang.org/docs/handbook/utility-types.html#readonlytype',
Record: 'https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type',
Pick: 'https://www.typescriptlang.org/docs/handbook/utility-types.html#picktype-keys',
Omit: 'https://www.typescriptlang.org/docs/handbook/utility-types.html#omittype-keys',
Exclude: 'https://www.typescriptlang.org/docs/handbook/utility-types.html#excludeuniontype-excludedmembers',
Extract: 'https://www.typescriptlang.org/docs/handbook/utility-types.html#extracttype-union',
NonNullable: 'https://www.typescriptlang.org/docs/handbook/utility-types.html#nonnullabletype',
Parameters: 'https://www.typescriptlang.org/docs/handbook/utility-types.html#parameterstype',
ConstructorParameters: 'https://www.typescriptlang.org/docs/handbook/utility-types.html#constructorparameterstype',
ReturnType: 'https://www.typescriptlang.org/docs/handbook/utility-types.html#returntypetype',
InstanceType: 'https://www.typescriptlang.org/docs/handbook/utility-types.html#instancetypetype',
ThisParameterType: 'https://www.typescriptlang.org/docs/handbook/utility-types.html#thisparametertypetype',
OmitThisParameter: 'https://www.typescriptlang.org/docs/handbook/utility-types.html#omitthisparametertype',
ThisType: 'https://www.typescriptlang.org/docs/handbook/utility-types.html#thistypetype',
Uppercase: 'https://www.typescriptlang.org/docs/handbook/utility-types.html#uppercasestringtype',
Lowercase: 'https://www.typescriptlang.org/docs/handbook/utility-types.html#lowercasestringtype',
Capitalize: 'https://www.typescriptlang.org/docs/handbook/utility-types.html#capitalizestringtype',
Uncapitalize: 'https://www.typescriptlang.org/docs/handbook/utility-types.html#uncapitalizestringtype',
// External Libraries
AsyncEventEmitter: 'https://github.com/vladfrangu/async_event_emitter',
AsyncQueue: 'https://www.sapphirejs.dev/docs/Documentation/api-utilities/classes/sapphire_async_queue.AsyncQueue',
Redis: 'https://redis.github.io/ioredis/classes/Redis.html',
'prism.opus.Encoder': 'https://amishshah.github.io/prism-media/opus.Encoder.html',
'prism.VolumeTransformer': 'https://amishshah.github.io/prism-media/core.VolumeTransformer.html',
} as const;

View File

@@ -18,10 +18,10 @@ import type {
ApiProperty,
ApiPropertySignature,
ApiTypeAlias,
ApiTypeParameterListMixin,
ApiVariable,
} from '@discordjs/api-extractor-model';
import {
ApiTypeParameterListMixin,
Excerpt,
Meaning,
ApiAbstractMixin,
@@ -49,6 +49,7 @@ import type {
DocComment,
} from '@microsoft/tsdoc';
import type { DeclarationReference } from '@microsoft/tsdoc/lib-commonjs/beta/DeclarationReference.js';
import { BuiltinDocumentationLinks } from './builtinDocumentationLinks.js';
import { PACKAGES, fetchVersionDocs, fetchVersions } from './shared.js';
function resolvePackageName(packageName: string) {
@@ -225,7 +226,7 @@ function resolveItemURI(item: ApiItemLike): string {
: `${item.parent.displayName}:${item.parent.kind}#${item.displayName}`;
}
function itemExcerptText(excerpt: Excerpt, apiPackage: ApiPackage) {
function itemExcerptText(excerpt: Excerpt, apiPackage: ApiPackage, parent?: ApiTypeParameterListMixin) {
const DISCORD_API_TYPES_VERSION = 'v10';
const DISCORD_API_TYPES_DOCS_URL = `https://discord-api-types.dev/api/discord-api-types-${DISCORD_API_TYPES_VERSION}`;
@@ -286,6 +287,27 @@ function itemExcerptText(excerpt: Excerpt, apiPackage: ApiPackage) {
};
}
if (token.text in BuiltinDocumentationLinks) {
return {
text: token.text,
href: BuiltinDocumentationLinks[token.text as keyof typeof BuiltinDocumentationLinks],
};
}
if (parent?.typeParameters.some((type) => type.name === token.text)) {
const [packageName, parentItem] = parent.canonicalReference.toString().split('!');
return {
text: token.text,
resolvedItem: {
kind: 'TypeParameter',
displayName: token.text,
containerKey: `${parent.containerKey}|${token.text}`,
uri: `${parentItem}#${token.text}`,
packageName: packageName?.replace('@discordjs/', ''),
},
};
}
return {
text: token.text,
};
@@ -346,9 +368,19 @@ function itemTsDoc(item: DocNode, apiItem: ApiItem) {
const resolved = resolveCanonicalReference(codeDestination, apiItem.getAssociatedPackage());
if (!foundItem && !resolved) {
const itemName = codeDestination.memberReferences[0]?.memberIdentifier?.identifier;
if (itemName && itemName in BuiltinDocumentationLinks) {
return {
kind: DocNodeKind.LinkTag,
text: itemName,
uri: BuiltinDocumentationLinks[itemName as keyof typeof BuiltinDocumentationLinks],
};
}
return {
kind: DocNodeKind.LinkTag,
text: codeDestination.memberReferences[0]?.memberIdentifier?.identifier ?? null,
text: itemName ?? null,
};
}
@@ -482,6 +514,7 @@ function itemTsDoc(item: DocNode, apiItem: ApiItem) {
function itemInfo(item: ApiDeclaredItem) {
const sourceExcerpt = item.excerpt.text.trim();
const { sourceURL, sourceLine } = resolveFileUrl(item);
const isStatic = ApiStaticMixin.isBaseClassOf(item) && item.isStatic;
const isProtected = ApiProtectedMixin.isBaseClassOf(item) && item.isProtected;
@@ -489,14 +522,15 @@ function itemInfo(item: ApiDeclaredItem) {
const isAbstract = ApiAbstractMixin.isBaseClassOf(item) && item.isAbstract;
const isOptional = ApiOptionalMixin.isBaseClassOf(item) && item.isOptional;
const isDeprecated = Boolean(item.tsdocComment?.deprecatedBlock);
const isExternal = Boolean(item.sourceLocation.fileUrl?.includes('node_modules'));
const hasSummary = Boolean(item.tsdocComment?.summarySection);
return {
kind: item.kind,
displayName: item.displayName,
sourceURL: item.sourceLocation.fileUrl,
sourceLine: item.sourceLocation.fileLine,
sourceURL,
sourceLine,
sourceExcerpt,
summary: hasSummary ? itemTsDoc(item.tsdocComment!, item) : null,
isStatic,
@@ -505,6 +539,59 @@ function itemInfo(item: ApiDeclaredItem) {
isAbstract,
isDeprecated,
isOptional,
isExternal,
};
}
function resolveFileUrl(item: ApiDeclaredItem) {
const {
displayName,
kind,
sourceLocation: { fileUrl, fileLine },
} = item;
if (fileUrl?.includes('/node_modules/')) {
const [, pkg] = fileUrl.split('/node_modules/');
const parts = pkg?.split('/')[1]?.split('@');
const unscoped = parts?.[0]?.length;
if (!unscoped) parts?.shift();
const pkgName = parts?.shift();
const version = parts?.shift()?.split('_')?.[0];
// https://github.com/discordjs/discord.js/tree/main/node_modules/.pnpm/@discordjs+builders@1.9.0/node_modules/@discordjs/builders/dist/index.d.ts#L1764
// https://github.com/discordjs/discord.js/tree/main/node_modules/.pnpm/@discordjs+ws@1.1.1_bufferutil@4.0.8_utf-8-validate@6.0.4/node_modules/@discordjs/ws/dist/index.d.ts#L...
if (!unscoped && pkgName?.startsWith('discordjs+')) {
let currentItem = item;
while (currentItem.parent && currentItem.parent.kind !== ApiItemKind.EntryPoint)
currentItem = currentItem.parent as ApiDeclaredItem;
return {
sourceURL: `/docs/packages/${pkgName.replace('discordjs+', '')}/${version}/${currentItem.displayName}:${currentItem.kind}`,
};
}
// https://github.com/discordjs/discord.js/tree/main/node_modules/.pnpm/discord-api-types@0.37.97/node_modules/discord-api-types/payloads/v10/gateway.d.ts#L240
if (pkgName === 'discord-api-types') {
const DISCORD_API_TYPES_VERSION = 'v10';
const DISCORD_API_TYPES_DOCS_URL = `https://discord-api-types.dev/api/discord-api-types-${DISCORD_API_TYPES_VERSION}`;
let href = DISCORD_API_TYPES_DOCS_URL;
if (kind === ApiItemKind.EnumMember) {
href += `/enum/${item.parent!.displayName}#${displayName}`;
} else if (kind === ApiItemKind.TypeAlias || kind === ApiItemKind.Variable) {
href += `#${displayName}`;
} else {
href += `/${kindToMeaning.get(kind)}/${displayName}`;
}
return {
sourceURL: href,
};
}
}
return {
sourceURL: fileUrl,
sourceLine: fileLine,
};
}
@@ -534,6 +621,7 @@ function resolveParameters(item: ApiDocumentedItem & ApiParameterListMixin) {
isOptional: param.isOptional,
isRest: param.isRest,
parameterTypeExcerpt: param.parameterTypeExcerpt,
defaultValue: param.defaultValue,
};
});
}
@@ -553,9 +641,9 @@ function itemTypeParameters(item: ApiTypeParameterListMixin) {
return item.typeParameters.map((typeParam) => ({
name: typeParam.name,
constraintsExcerpt: itemExcerptText(typeParam.constraintExcerpt, item.getAssociatedPackage()!),
constraintsExcerpt: itemExcerptText(typeParam.constraintExcerpt, item.getAssociatedPackage()!, item),
isOptional: typeParam.isOptional,
defaultExcerpt: itemExcerptText(typeParam.defaultTypeExcerpt, item.getAssociatedPackage()!),
defaultExcerpt: itemExcerptText(typeParam.defaultTypeExcerpt, item.getAssociatedPackage()!, item),
description: typeParam.tsdocTypeParamBlock ? itemTsDoc(typeParam.tsdocTypeParamBlock.content, item) : null,
}));
}
@@ -572,9 +660,14 @@ function itemParameters(item: ApiDocumentedItem & ApiParameterListMixin) {
return params.map((param) => ({
name: param.isRest ? `...${param.name}` : param.name,
typeExcerpt: itemExcerptText(param.parameterTypeExcerpt, item.getAssociatedPackage()!),
typeExcerpt: itemExcerptText(
param.parameterTypeExcerpt,
item.getAssociatedPackage()!,
item.getHierarchy().find(ApiTypeParameterListMixin.isBaseClassOf),
),
isOptional: param.isOptional,
description: param.description ? itemTsDoc(param.description, item) : null,
defaultValue: param.defaultValue,
}));
}
@@ -622,7 +715,11 @@ function itemProperty(item: ApiItemContainerMixin) {
return {
...itemInfo(property.item),
inheritedFrom: property.inherited ? resolveItemURI(property.inherited) : null,
typeExcerpt: itemExcerptText(property.item.propertyTypeExcerpt, property.item.getAssociatedPackage()!),
typeExcerpt: itemExcerptText(
property.item.propertyTypeExcerpt,
property.item.getAssociatedPackage()!,
property.item.getHierarchy().find(ApiTypeParameterListMixin.isBaseClassOf),
),
summary: hasSummary ? itemTsDoc(property.item.tsdocComment!, property.item) : null,
};
});
@@ -658,7 +755,11 @@ function itemMethod(item: ApiItemContainerMixin) {
...itemInfo(method.item),
overloadIndex: method.item.overloadIndex,
parametersString: parametersString(method.item),
returnTypeExcerpt: itemExcerptText(method.item.returnTypeExcerpt, method.item.getAssociatedPackage()!),
returnTypeExcerpt: itemExcerptText(
method.item.returnTypeExcerpt,
method.item.getAssociatedPackage()!,
method.item.getHierarchy().find(ApiTypeParameterListMixin.isBaseClassOf),
),
inheritedFrom: method.inherited ? resolveItemURI(method.inherited) : null,
typeParameters: itemTypeParameters(method.item),
parameters: itemParameters(method.item),
@@ -754,7 +855,11 @@ export function itemHierarchyText({
return excerpts.map((excerpt) => {
return {
type,
excerpts: itemExcerptText(excerpt, item.getAssociatedPackage()!),
excerpts: itemExcerptText(
excerpt,
item.getAssociatedPackage()!,
item.getHierarchy().find(ApiTypeParameterListMixin.isBaseClassOf),
),
};
});
}
@@ -848,7 +953,11 @@ function itemTypeAlias(item: ApiTypeAlias) {
...itemInfo(item),
typeParameters: itemTypeParameters(item),
unionMembers: itemUnion(item).map((member) =>
itemExcerptText(new Excerpt(member, { startIndex: 0, endIndex: member.length }), item.getAssociatedPackage()!),
itemExcerptText(
new Excerpt(member, { startIndex: 0, endIndex: member.length }),
item.getAssociatedPackage()!,
item.getHierarchy().find(ApiTypeParameterListMixin.isBaseClassOf),
),
),
};
}

View File

@@ -7,6 +7,7 @@
<p>
<a href="https://discord.gg/djs"><img src="https://img.shields.io/discord/222078108977594368?color=5865F2&logo=discord&logoColor=white" alt="Discord server" /></a>
<a href="https://github.com/discordjs/discord.js/actions"><img src="https://github.com/discordjs/discord.js/actions/workflows/test.yml/badge.svg" alt="Build status" /></a>
<a href="https://github.com/discordjs/discord.js/commits/main/packages/util"><img alt="Last commit." src="https://img.shields.io/github/last-commit/discordjs/discord.js?logo=github&logoColor=ffffff&path=packages%2Futil"></a>
</p>
<p>
<a href="https://vercel.com/?utm_source=discordjs&utm_campaign=oss"><img src="https://raw.githubusercontent.com/discordjs/discord.js/main/.github/powered-by-vercel.svg" alt="Vercel" /></a>

View File

@@ -9,7 +9,8 @@
<a href="https://www.npmjs.com/package/@discordjs/voice"><img src="https://img.shields.io/npm/v/@discordjs/voice.svg?maxAge=3600" alt="npm version" /></a>
<a href="https://www.npmjs.com/package/@discordjs/voice"><img src="https://img.shields.io/npm/dt/@discordjs/voice.svg?maxAge=3600" alt="npm downloads" /></a>
<a href="https://github.com/discordjs/discord.js/actions"><img src="https://github.com/discordjs/discord.js/actions/workflows/test.yml/badge.svg" alt="Build status" /></a>
<a href="https://codecov.io/gh/discordjs/discord.js" ><img src="https://codecov.io/gh/discordjs/discord.js/branch/main/graph/badge.svg?precision=2&flag=voice" alt="Code coverage" /></a>
<a href="https://github.com/discordjs/discord.js/commits/main/packages/voice"><img alt="Last commit." src="https://img.shields.io/github/last-commit/discordjs/discord.js?logo=github&logoColor=ffffff&path=packages%2Fvoice"></a>
<a href="https://codecov.io/gh/discordjs/discord.js"><img src="https://codecov.io/gh/discordjs/discord.js/branch/main/graph/badge.svg?precision=2&flag=voice" alt="Code coverage" /></a>
</p>
<p>
<a href="https://vercel.com/?utm_source=discordjs&utm_campaign=oss"><img src="https://raw.githubusercontent.com/discordjs/discord.js/main/.github/powered-by-vercel.svg" alt="Vercel" /></a>

View File

@@ -64,7 +64,7 @@
"funding": "https://github.com/discordjs/discord.js?sponsor",
"dependencies": {
"@types/ws": "^8.5.12",
"discord-api-types": "^0.37.114",
"discord-api-types": "^0.37.119",
"prism-media": "^1.3.5",
"tslib": "^2.6.3",
"ws": "^8.18.0"

View File

@@ -9,7 +9,8 @@
<a href="https://www.npmjs.com/package/@discordjs/ws"><img src="https://img.shields.io/npm/v/@discordjs/ws.svg?maxAge=3600" alt="npm version" /></a>
<a href="https://www.npmjs.com/package/@discordjs/ws"><img src="https://img.shields.io/npm/dt/@discordjs/ws.svg?maxAge=3600" alt="npm downloads" /></a>
<a href="https://github.com/discordjs/discord.js/actions"><img src="https://github.com/discordjs/discord.js/actions/workflows/test.yml/badge.svg" alt="Build status" /></a>
<a href="https://codecov.io/gh/discordjs/discord.js" ><img src="https://codecov.io/gh/discordjs/discord.js/branch/main/graph/badge.svg?precision=2&flag=ws" alt="Code coverage" /></a>
<a href="https://github.com/discordjs/discord.js/commits/main/packages/ws"><img alt="Last commit." src="https://img.shields.io/github/last-commit/discordjs/discord.js?logo=github&logoColor=ffffff&path=packages%2Fws"></a>
<a href="https://codecov.io/gh/discordjs/discord.js"><img src="https://codecov.io/gh/discordjs/discord.js/branch/main/graph/badge.svg?precision=2&flag=ws" alt="Code coverage" /></a>
</p>
<p>
<a href="https://vercel.com/?utm_source=discordjs&utm_campaign=oss"><img src="https://raw.githubusercontent.com/discordjs/discord.js/main/.github/powered-by-vercel.svg" alt="Vercel" /></a>

View File

@@ -79,7 +79,7 @@
"@sapphire/async-queue": "^1.5.3",
"@types/ws": "^8.5.12",
"@vladfrangu/async_event_emitter": "^2.4.6",
"discord-api-types": "^0.37.114",
"discord-api-types": "^0.37.119",
"tslib": "^2.6.3",
"ws": "^8.18.0"
},
@@ -100,7 +100,7 @@
"tsup": "^8.2.4",
"turbo": "^2.0.14",
"typescript": "~5.5.4",
"undici": "6.19.8",
"undici": "6.21.1",
"vitest": "^2.0.5",
"zlib-sync": "^0.1.9"
},

130
pnpm-lock.yaml generated
View File

@@ -408,8 +408,8 @@ importers:
specifier: ^2.6.3
version: 2.6.3
undici:
specifier: 6.19.8
version: 6.19.8
specifier: 6.21.1
version: 6.21.1
devDependencies:
'@types/node':
specifier: ^18.19.45
@@ -680,8 +680,8 @@ importers:
specifier: ^4.0.0
version: 4.0.0
discord-api-types:
specifier: ^0.37.114
version: 0.37.114
specifier: ^0.37.119
version: 0.37.119
fast-deep-equal:
specifier: ^3.1.3
version: 3.1.3
@@ -804,8 +804,8 @@ importers:
specifier: ^2.4.6
version: 2.4.6
discord-api-types:
specifier: ^0.37.114
version: 0.37.114
specifier: ^0.37.119
version: 0.37.119
devDependencies:
'@discordjs/api-extractor':
specifier: workspace:^
@@ -941,8 +941,8 @@ importers:
specifier: 3.5.3
version: 3.5.3
discord-api-types:
specifier: ^0.37.114
version: 0.37.114
specifier: ^0.37.119
version: 0.37.119
fast-deep-equal:
specifier: 3.1.3
version: 3.1.3
@@ -953,8 +953,8 @@ importers:
specifier: ^2.6.3
version: 2.6.3
undici:
specifier: 6.19.8
version: 6.19.8
specifier: 6.21.1
version: 6.21.1
devDependencies:
'@discordjs/api-extractor':
specifier: workspace:^
@@ -1060,8 +1060,8 @@ importers:
packages/formatters:
dependencies:
discord-api-types:
specifier: ^0.37.114
version: 0.37.114
specifier: ^0.37.119
version: 0.37.119
devDependencies:
'@discordjs/api-extractor':
specifier: workspace:^
@@ -1133,8 +1133,8 @@ importers:
specifier: workspace:^
version: link:../ws
discord-api-types:
specifier: ^0.37.114
version: 0.37.114
specifier: ^0.37.119
version: 0.37.119
devDependencies:
'@discordjs/api-extractor':
specifier: workspace:^
@@ -1194,8 +1194,8 @@ importers:
specifier: ^2.6.3
version: 2.6.3
undici:
specifier: 6.19.8
version: 6.19.8
specifier: 6.21.1
version: 6.21.1
devDependencies:
'@discordjs/api-extractor':
specifier: workspace:^
@@ -1307,8 +1307,8 @@ importers:
specifier: ^2.4.6
version: 2.4.6
discord-api-types:
specifier: ^0.37.114
version: 0.37.114
specifier: ^0.37.119
version: 0.37.119
magic-bytes.js:
specifier: ^1.10.0
version: 1.10.0
@@ -1316,8 +1316,8 @@ importers:
specifier: ^2.6.3
version: 2.6.3
undici:
specifier: 6.19.8
version: 6.19.8
specifier: 6.21.1
version: 6.21.1
devDependencies:
'@discordjs/api-extractor':
specifier: workspace:^
@@ -1395,8 +1395,8 @@ importers:
specifier: ^2.6.3
version: 2.6.3
undici:
specifier: 6.19.8
version: 6.19.8
specifier: 6.21.1
version: 6.21.1
yaml:
specifier: ^2.5.0
version: 2.5.0
@@ -1604,8 +1604,8 @@ importers:
specifier: ^8.5.12
version: 8.5.12
discord-api-types:
specifier: ^0.37.114
version: 0.37.114
specifier: ^0.37.119
version: 0.37.119
prism-media:
specifier: ^1.3.5
version: 1.3.5
@@ -1701,8 +1701,8 @@ importers:
specifier: ^2.4.6
version: 2.4.6
discord-api-types:
specifier: ^0.37.114
version: 0.37.114
specifier: ^0.37.119
version: 0.37.119
tslib:
specifier: ^2.6.3
version: 2.6.3
@@ -1759,8 +1759,8 @@ importers:
specifier: ~5.5.4
version: 5.5.4
undici:
specifier: 6.19.8
version: 6.19.8
specifier: 6.21.1
version: 6.21.1
vitest:
specifier: ^2.0.5
version: 2.0.5(@edge-runtime/vm@3.2.0)(@types/node@18.19.45)(happy-dom@14.12.3)(terser@5.31.6)
@@ -5700,8 +5700,8 @@ packages:
'@types/node@18.19.45':
resolution: {integrity: sha512-VZxPKNNhjKmaC1SUYowuXSRSMGyQGmQjvvA1xE4QZ0xce2kLtEhPDS+kqpCPBZYgqblCLQ2DAjSzmgCM5auvhA==}
'@types/node@18.19.68':
resolution: {integrity: sha512-QGtpFH1vB99ZmTa63K4/FU8twThj4fuVSBkGddTp7uIL/cuoLWIUSL2RcOaigBhfR+hg5pgGkBnkoOxrTVBMKw==}
'@types/node@18.19.74':
resolution: {integrity: sha512-HMwEkkifei3L605gFdV+/UwtpxP6JSzM+xFk2Ia6DNFSwSVBRh9qp5Tgf4lNFOMfPVuU0WnkcWpXZpgn5ufO4A==}
'@types/node@20.16.1':
resolution: {integrity: sha512-zJDo7wEadFtSyNz5QITDfRcrhqDvQI1xQNQ0VoizPjM/dVAODqqIUWbJPkvsxmTI0MYRGRikcdjMPhOssnPejQ==}
@@ -6673,8 +6673,8 @@ packages:
balanced-match@1.0.2:
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
bare-events@2.5.0:
resolution: {integrity: sha512-/E8dDe9dsbLyh2qrZ64PEPadOQ0F4gbl1sUJOrmph7xOiIxfY8vwab/4bFLh4Y88/Hk/ujKcrQKc+ps0mv873A==}
bare-events@2.5.4:
resolution: {integrity: sha512-+gFfDkR8pj4/TrWCGUGWmJIkBwuxPS5F+a5yWjOHQt2hHvNZd5YLzadjmDUtFmMM4y429bnKLa8bYBMHcYdnQA==}
base64-js@0.0.8:
resolution: {integrity: sha512-3XSA2cR/h/73EzlXXdU6YNycmYI7+kicTxks4eJg2g39biHR84slg2+des+p7iHYhbRg/udIS4TD53WabcOUkw==}
@@ -7644,8 +7644,8 @@ packages:
resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==}
engines: {node: '>=8'}
discord-api-types@0.37.114:
resolution: {integrity: sha512-9b9oOpktWSmE6ooToc46wfw151SHC/+idmnZvtwpEzW85BijUspQxj4W2uOmo+nZVTdEyb3fku58k+4rHKpdSQ==}
discord-api-types@0.37.119:
resolution: {integrity: sha512-WasbGFXEB+VQWXlo6IpW3oUv73Yuau1Ig4AZF/m13tXcTKnMpc/mHjpztIlz4+BM9FG9BHQkEXiPto3bKduQUg==}
dlv@1.1.3:
resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==}
@@ -8657,12 +8657,12 @@ packages:
resolution: {integrity: sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==}
engines: {node: '>= 0.4'}
get-tsconfig@4.10.0:
resolution: {integrity: sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A==}
get-tsconfig@4.7.6:
resolution: {integrity: sha512-ZAqrLlu18NbDdRaHq+AKXzAmqIUPswPWKUchfytdAjiRFnCe5ojG2bstg6mRiZabkKfCoL/e98pbBELIV/YCeA==}
get-tsconfig@4.8.1:
resolution: {integrity: sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==}
get-uri@6.0.3:
resolution: {integrity: sha512-BzUrJBS9EcUb4cFol8r4W3v1cPsSyajLSthNkz5BxbpDcHN5tIrM10E2eNvfnvBn3DaT3DUgx0OpsBKkaOpanw==}
engines: {node: '>= 14'}
@@ -11563,9 +11563,6 @@ packages:
queue-microtask@1.2.3:
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
queue-tick@1.0.1:
resolution: {integrity: sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==}
quick-lru@4.0.1:
resolution: {integrity: sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==}
engines: {node: '>=8'}
@@ -12340,8 +12337,8 @@ packages:
resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==}
engines: {node: '>=10.0.0'}
streamx@2.21.1:
resolution: {integrity: sha512-PhP9wUnFLa+91CPy3N6tiQsK+gnYyUNuk15S3YG/zjYE7RuPeCjJngqnzpC31ow0lzBHQ+QGO4cNJnd0djYUsw==}
streamx@2.22.0:
resolution: {integrity: sha512-sLh1evHOzBy/iWRiR6d1zRcLao4gGZr3C1kzNz4fopCOKJb6xD9ub8Mpi9Mr1R6id5o43S+d93fI48UC5uM9aw==}
string-argv@0.3.2:
resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==}
@@ -13082,6 +13079,10 @@ packages:
resolution: {integrity: sha512-U8uCCl2x9TK3WANvmBavymRzxbfFYG+tAu+fgx3zxQy3qdagQqBLwJVrdyO1TBfUXvfKveMKJZhpvUYoOjM+4g==}
engines: {node: '>=18.17'}
undici@6.21.1:
resolution: {integrity: sha512-q/1rj5D0/zayJB2FraXdaWxbhWiNKDvu8naDT2dl1yTlvJp4BLtOcp2a5BvgGNQpYYJzau7tf1WgKv3b+7mqpQ==}
engines: {node: '>=18.17'}
unicode-canonical-property-names-ecmascript@2.0.0:
resolution: {integrity: sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==}
engines: {node: '>=4'}
@@ -14865,7 +14866,7 @@ snapshots:
'@definitelytyped/utils@0.1.8':
dependencies:
'@qiwi/npm-registry-client': 8.9.1
'@types/node': 18.19.68
'@types/node': 18.19.74
cachedir: 2.4.0
charm: 1.0.2
minimatch: 9.0.5
@@ -14878,7 +14879,7 @@ snapshots:
'@discordjs/formatters': 0.6.0
'@discordjs/util': 1.1.1
'@sapphire/shapeshift': 4.0.0
discord-api-types: 0.37.114
discord-api-types: 0.37.119
fast-deep-equal: 3.1.3
ts-mixer: 6.0.4
tslib: 2.6.3
@@ -14891,7 +14892,7 @@ snapshots:
'@discordjs/formatters@0.6.0':
dependencies:
discord-api-types: 0.37.114
discord-api-types: 0.37.119
'@discordjs/rest@2.4.1':
dependencies:
@@ -14900,7 +14901,7 @@ snapshots:
'@sapphire/async-queue': 1.5.3
'@sapphire/snowflake': 3.5.3
'@vladfrangu/async_event_emitter': 2.4.6
discord-api-types: 0.37.114
discord-api-types: 0.37.119
magic-bytes.js: 1.10.0
tslib: 2.6.3
undici: 6.19.8
@@ -14915,7 +14916,7 @@ snapshots:
'@sapphire/async-queue': 1.5.3
'@types/ws': 8.5.12
'@vladfrangu/async_event_emitter': 2.4.6
discord-api-types: 0.37.114
discord-api-types: 0.37.119
tslib: 2.6.3
ws: 8.18.0(bufferutil@4.0.8)(utf-8-validate@6.0.4)
transitivePeerDependencies:
@@ -16205,7 +16206,7 @@ snapshots:
'@opentelemetry/propagator-b3': 1.25.1(@opentelemetry/api@1.9.0)
'@opentelemetry/propagator-jaeger': 1.25.1(@opentelemetry/api@1.9.0)
'@opentelemetry/sdk-trace-base': 1.25.1(@opentelemetry/api@1.9.0)
semver: 7.5.4
semver: 7.6.3
'@opentelemetry/semantic-conventions@1.15.2': {}
@@ -18019,7 +18020,7 @@ snapshots:
fs-extra: 7.0.1
import-lazy: 4.0.0
jju: 1.4.0
resolve: 1.22.10
resolve: 1.22.8
semver: 7.5.4
z-schema: 5.0.5
optionalDependencies:
@@ -18031,7 +18032,7 @@ snapshots:
fs-extra: 7.0.1
import-lazy: 4.0.0
jju: 1.4.0
resolve: 1.22.10
resolve: 1.22.8
semver: 7.5.4
z-schema: 5.0.5
optionalDependencies:
@@ -18043,7 +18044,7 @@ snapshots:
fs-extra: 7.0.1
import-lazy: 4.0.0
jju: 1.4.0
resolve: 1.22.10
resolve: 1.22.8
semver: 7.5.4
z-schema: 5.0.5
optionalDependencies:
@@ -18054,7 +18055,7 @@ snapshots:
fs-extra: 7.0.1
import-lazy: 4.0.0
jju: 1.4.0
resolve: 1.22.10
resolve: 1.22.8
semver: 7.5.4
z-schema: 5.0.5
optionalDependencies:
@@ -18079,7 +18080,7 @@ snapshots:
'@rushstack/rig-package@0.5.2':
dependencies:
resolve: 1.22.10
resolve: 1.22.8
strip-json-comments: 3.1.1
'@rushstack/terminal@0.10.0(@types/node@16.18.105)':
@@ -19109,7 +19110,7 @@ snapshots:
dependencies:
undici-types: 5.26.5
'@types/node@18.19.68':
'@types/node@18.19.74':
dependencies:
undici-types: 5.26.5
@@ -20531,7 +20532,7 @@ snapshots:
balanced-match@1.0.2: {}
bare-events@2.5.0:
bare-events@2.5.4:
optional: true
base64-js@0.0.8: {}
@@ -21529,7 +21530,7 @@ snapshots:
dependencies:
path-type: 4.0.0
discord-api-types@0.37.114: {}
discord-api-types@0.37.119: {}
dlv@1.1.3: {}
@@ -22178,7 +22179,7 @@ snapshots:
eslint: 8.57.0
eslint-import-resolver-node: 0.3.9
eslint-module-utils: 2.12.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint-plugin-i@2.29.1)(eslint@8.57.0))(eslint@8.57.0)
get-tsconfig: 4.8.1
get-tsconfig: 4.10.0
is-glob: 4.0.3
minimatch: 3.1.2
semver: 7.5.4
@@ -22974,11 +22975,11 @@ snapshots:
es-errors: 1.3.0
get-intrinsic: 1.2.4
get-tsconfig@4.7.6:
get-tsconfig@4.10.0:
dependencies:
resolve-pkg-maps: 1.0.0
get-tsconfig@4.8.1:
get-tsconfig@4.7.6:
dependencies:
resolve-pkg-maps: 1.0.0
@@ -26825,8 +26826,6 @@ snapshots:
queue-microtask@1.2.3: {}
queue-tick@1.0.1: {}
quick-lru@4.0.1: {}
raf@3.4.1:
@@ -27937,13 +27936,12 @@ snapshots:
streamsearch@1.1.0: {}
streamx@2.21.1:
streamx@2.22.0:
dependencies:
fast-fifo: 1.3.2
queue-tick: 1.0.1
text-decoder: 1.2.3
optionalDependencies:
bare-events: 2.5.0
bare-events: 2.5.4
string-argv@0.3.2: {}
@@ -28211,7 +28209,7 @@ snapshots:
dependencies:
b4a: 1.6.7
fast-fifo: 1.3.2
streamx: 2.21.1
streamx: 2.22.0
tar@4.4.18:
dependencies:
@@ -28829,6 +28827,8 @@ snapshots:
undici@6.19.8: {}
undici@6.21.1: {}
unicode-canonical-property-names-ecmascript@2.0.0: {}
unicode-match-property-ecmascript@2.0.0: