diff --git a/apps/website/src/components/Badges.tsx b/apps/website/src/components/Badges.tsx
index b040aa0ebc1e..2f8514d72722 100644
--- a/apps/website/src/components/Badges.tsx
+++ b/apps/website/src/components/Badges.tsx
@@ -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 ? (
@@ -33,6 +34,7 @@ export async function Badges({ node }: { readonly node: any }) {
{isAbstract ? abstract : null}
{isReadonly ? readonly : null}
{isOptional ? optional : null}
+ {isExternal ? external : null}
) : null;
}
diff --git a/packages/core/api-extractor.json b/packages/core/api-extractor.json
index 66d1b5841b6b..c8cad5a5c924 100644
--- a/packages/core/api-extractor.json
+++ b/packages/core/api-extractor.json
@@ -1,5 +1,6 @@
{
"extends": "../../api-extractor.json",
+ "bundledPackages": ["discord-api-types"],
"docModel": {
"projectFolderUrl": "https://github.com/discordjs/discord.js/tree/main/packages/core"
}
diff --git a/packages/discord.js/api-extractor.json b/packages/discord.js/api-extractor.json
index 80ba4deedceb..0e5a315890ed 100644
--- a/packages/discord.js/api-extractor.json
+++ b/packages/discord.js/api-extractor.json
@@ -1,6 +1,14 @@
{
"extends": "../../api-extractor.json",
"mainEntryPointFilePath": "/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"
}
diff --git a/packages/scripts/src/generateSplitDocumentation.ts b/packages/scripts/src/generateSplitDocumentation.ts
index ee83a2b6f2b3..85923ae06c93 100644
--- a/packages/scripts/src/generateSplitDocumentation.ts
+++ b/packages/scripts/src/generateSplitDocumentation.ts
@@ -514,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;
@@ -521,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,
@@ -537,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,
};
}