From cbe8fa901b33ab702f42f40bfeb7bf360c96fa22 Mon Sep 17 00:00:00 2001
From: Qjuh <76154676+Qjuh@users.noreply.github.com>
Date: Sat, 11 Nov 2023 09:29:23 +0100
Subject: [PATCH 1/6] refactor: use tokenRange for typeParams in heritage
---
apps/website/src/components/ExcerptText.tsx | 18 ++--
.../src/components/TableOfContentItems.tsx | 2 +-
.../src/mixins/ApiItemContainerMixin.ts | 86 +++++++++----------
.../api-extractor-model/src/model/ApiClass.ts | 2 +-
.../src/model/DeserializerContext.ts | 7 +-
.../src/model/HeritageType.ts | 6 +-
.../src/generators/ApiModelGenerator.ts | 36 +++++---
.../src/generators/ExcerptBuilder.ts | 21 +++--
8 files changed, 97 insertions(+), 81 deletions(-)
diff --git a/apps/website/src/components/ExcerptText.tsx b/apps/website/src/components/ExcerptText.tsx
index adf6b4383ace..f2b2243461ca 100644
--- a/apps/website/src/components/ExcerptText.tsx
+++ b/apps/website/src/components/ExcerptText.tsx
@@ -22,8 +22,6 @@ export function ExcerptText({ model, excerpt }: ExcerptTextProps) {
return (
{excerpt.spannedTokens.map((token, idx) => {
- // TODO: Real fix in api-extractor needed
- const text = token.text.replaceAll('\n', '').replaceAll(/\s{2}$/g, '');
if (token.kind === ExcerptTokenKind.Reference) {
const source = token.canonicalReference?.source;
const symbol = token.canonicalReference?.symbol;
@@ -34,20 +32,22 @@ export function ExcerptText({ model, excerpt }: ExcerptTextProps) {
// dapi-types doesn't have routes for class members
// so we can assume this member is for an enum
if (meaning === 'member' && path && 'parent' in path) href += `/enum/${path.parent}#${path.component}`;
- else if (meaning === 'type') href += `#${text}`;
- else href += `/${meaning}/${text}`;
+ else if (meaning === 'type' || meaning === 'var') href += `#${token.text}`;
+ else href += `/${meaning}/${token.text}`;
return (
- {text}
+ {token.text}
);
}
- const item = model.resolveDeclarationReference(token.canonicalReference!, model).resolvedApiItem;
+ const item = token.canonicalReference
+ ? model.resolveDeclarationReference(token.canonicalReference!, model).resolvedApiItem
+ : null;
if (!item) {
- return text;
+ return token.text;
}
return (
@@ -57,12 +57,12 @@ export function ExcerptText({ model, excerpt }: ExcerptTextProps) {
key={`${item.displayName}-${item.containerKey}-${idx}`}
packageName={item.getAssociatedPackage()?.displayName.replace('@discordjs/', '')}
>
- {text}
+ {token.text}
);
}
- return text.replace(/import\("discord-api-types(?:\/v\d+)?"\)\./, '');
+ return token.text.replace(/import\("discord-api-types(?:\/v\d+)?"\)\./, '');
})}
);
diff --git a/apps/website/src/components/TableOfContentItems.tsx b/apps/website/src/components/TableOfContentItems.tsx
index 544b25c785d9..a1e33316085f 100644
--- a/apps/website/src/components/TableOfContentItems.tsx
+++ b/apps/website/src/components/TableOfContentItems.tsx
@@ -127,7 +127,7 @@ export function TableOfContentItems({ serializedMembers }: TableOfContentsItemPr
{eventItems}
diff --git a/packages/api-extractor-model/src/mixins/ApiItemContainerMixin.ts b/packages/api-extractor-model/src/mixins/ApiItemContainerMixin.ts
index 9da10d3eb5ab..3782457bca38 100644
--- a/packages/api-extractor-model/src/mixins/ApiItemContainerMixin.ts
+++ b/packages/api-extractor-model/src/mixins/ApiItemContainerMixin.ts
@@ -1,9 +1,13 @@
+/* eslint-disable @typescript-eslint/no-loop-func */
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.
+import { TSDocConfiguration } from '@microsoft/tsdoc';
import type { DeclarationReference } from '@microsoft/tsdoc/lib-commonjs/beta/DeclarationReference.js';
import { InternalError } from '@rushstack/node-core-library';
-import type { ApiDeclaredItem } from '../index.js';
+import type { IExcerptToken, IExcerptTokenRange } from '../index.js';
+import { ApiDeclaredItem } from '../index.js';
+import type { IApiDeclaredItemJson } from '../items/ApiDeclaredItem.js';
import {
ApiItem,
apiItem_onParentChanged,
@@ -15,11 +19,12 @@ import {
import type { ApiClass } from '../model/ApiClass.js';
import type { ApiInterface } from '../model/ApiInterface.js';
import type { ApiModel } from '../model/ApiModel.js';
-import type { DeserializerContext } from '../model/DeserializerContext.js';
+import { ApiJsonSchemaVersion, type DeserializerContext } from '../model/DeserializerContext.js';
import type { HeritageType } from '../model/HeritageType.js';
import type { IResolveDeclarationReferenceResult } from '../model/ModelReferenceResolver.js';
import { ApiNameMixin } from './ApiNameMixin.js';
-import { type ExcerptToken, ExcerptTokenKind } from './Excerpt.js';
+import type { ExcerptToken } from './Excerpt.js';
+import { ExcerptTokenKind } from './Excerpt.js';
import { type IFindApiItemsResult, type IFindApiItemsMessage, FindApiItemsMessageId } from './IFindApiItemsResult.js';
/**
@@ -39,7 +44,7 @@ export interface IApiItemContainerJson extends IApiItemJson {
interface IMappedTypeParameters {
item: ApiItem;
- mappedTypeParameters: Map;
+ mappedTypeParameters: Map;
}
const _members: unique symbol = Symbol('ApiItemContainerMixin._members');
@@ -317,7 +322,7 @@ export function ApiItemContainerMixin(
let next: IMappedTypeParameters | undefined = { item: this, mappedTypeParameters: new Map() };
while (next?.item) {
- const membersToAdd: ApiItem[] = []; /*
+ const membersToAdd: ApiItem[] = []; //*
const typeParams = next.mappedTypeParameters;
const context: DeserializerContext = {
apiJsonFilename: '',
@@ -325,56 +330,43 @@ export function ApiItemContainerMixin(
toolVersion: '',
versionToDeserialize: ApiJsonSchemaVersion.LATEST,
tsdocConfiguration: new TSDocConfiguration(),
- }; */
+ }; // */
+
+ // eslint-disable-next-line @typescript-eslint/consistent-type-imports, @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires
+ const deserializerModule: typeof import('../model/Deserializer') = require('../model/Deserializer');
// For each member, check to see if we've already seen a member with the same name
// previously in the inheritance tree. If so, we know we won't inherit it, and thus
// do not add it to our `membersToAdd` array.
- for (const member of next.item.members) {
+ for (let member of next.item.members) {
// We add the to-be-added members to an intermediate array instead of immediately
// to the maps themselves to support method overloads with the same name.
- if (ApiNameMixin.isBaseClassOf(member)) {
- if (!membersByName.has(member.name)) {
- // This was supposed to replace type parameters with their assigned values in inheritance, but doesn't work yet
- /*
- if (
- ApiTypeParameterListMixin.isBaseClassOf(member) &&
- member.typeParameters.some((param) => typeParams.has(param.name))
- ) {
- const jsonObject: Partial = {};
- member.serializeInto(jsonObject);
- member = deserializerModule.Deserializer.deserialize(context, {
- ...jsonObject,
- typeParameters: (jsonObject as IApiTypeParameterListMixinJson).typeParameters.map(
- ({ typeParameterName, constraintTokenRange, defaultTypeTokenRange }) => ({
- typeParameterName: typeParams.get(typeParameterName) ?? typeParameterName,
- defaultTypeTokenRange,
- constraintTokenRange,
- }),
- ),
- } as IApiTypeParameterListMixinJson);
+
+ // This was supposed to replace type parameters with their assigned values in inheritance, but doesn't work yet
+ //*
+ if (member instanceof ApiDeclaredItem && member.excerptTokens.some((token) => typeParams.has(token.text))) {
+ const jsonObject: Partial = {};
+ member.serializeInto(jsonObject);
+ const excerptTokens = (jsonObject as IApiDeclaredItemJson).excerptTokens.map((token) => {
+ let x: ExcerptToken | undefined;
+ if (typeParams.has(token.text) && next?.item instanceof ApiDeclaredItem)
+ x = (member as ApiDeclaredItem).excerptTokens[typeParams.get(token.text)!.startIndex];
+ const excerptToken: IExcerptToken = x ? { kind: x.kind, text: x.text } : token;
+ if (x?.canonicalReference !== undefined) {
+ excerptToken.canonicalReference = x.canonicalReference.toString();
}
- if (ApiReturnTypeMixin.isBaseClassOf(member)) {
- const jsonObject: Partial = {};
- member.serializeInto(jsonObject);
- member = deserializerModule.Deserializer.deserialize(context, {
- ...(jsonObject as IApiReturnTypeMixinJson),
- excerptTokens: (jsonObject as IApiDeclaredItemJson).excerptTokens.map((token) =>
- token.kind === ExcerptTokenKind.Content
- ? {
- kind: ExcerptTokenKind.Content,
- text: [...typeParams.keys()].reduce(
- (tok, typ) => tok.replaceAll(new RegExp(`\b${typ}\b`, 'g'), typeParams.get(typ)!),
- token.text,
- ),
- }
- : token,
- ),
- } as IApiReturnTypeMixinJson);
- member[apiItem_onParentChanged](next.item);
- } // */
+ return excerptToken;
+ });
+ member = deserializerModule.Deserializer.deserialize(context, {
+ ...jsonObject,
+ excerptTokens,
+ } as IApiDeclaredItemJson);
+ member[apiItem_onParentChanged](next.item);
+ }
+ if (ApiNameMixin.isBaseClassOf(member)) {
+ if (!membersByName.has(member.name)) {
membersToAdd.push(member);
}
} else if (!membersByKind.has(member.kind)) {
@@ -478,7 +470,7 @@ export function ApiItemContainerMixin(
continue;
}
- const mappedTypeParameters: Map = new Map();
+ const mappedTypeParameters: Map = new Map();
if (
(apiItem.kind === ApiItemKind.Class || apiItem.kind === ApiItemKind.Interface) &&
next.item.kind === ApiItemKind.Class
diff --git a/packages/api-extractor-model/src/model/ApiClass.ts b/packages/api-extractor-model/src/model/ApiClass.ts
index e65a88bd84b5..7f8e86ec101b 100644
--- a/packages/api-extractor-model/src/model/ApiClass.ts
+++ b/packages/api-extractor-model/src/model/ApiClass.ts
@@ -44,7 +44,7 @@ export interface IApiClassOptions
}
export interface IExcerptTokenRangeWithTypeParameters extends IExcerptTokenRange {
- typeParameters: string[];
+ typeParameters: IExcerptTokenRange[];
}
export interface IApiClassJson
diff --git a/packages/api-extractor-model/src/model/DeserializerContext.ts b/packages/api-extractor-model/src/model/DeserializerContext.ts
index daf4de626498..b5778c8f961a 100644
--- a/packages/api-extractor-model/src/model/DeserializerContext.ts
+++ b/packages/api-extractor-model/src/model/DeserializerContext.ts
@@ -91,13 +91,18 @@ export enum ApiJsonSchemaVersion {
*/
V_1011 = 1_011,
+ /**
+ * Add a `fileLine`and `fileColumn` field to track source code location
+ */
+ V_1012 = 1_012,
+
/**
* The current latest .api.json schema version.
*
* IMPORTANT: When incrementing this number, consider whether `OLDEST_SUPPORTED` or `OLDEST_FORWARDS_COMPATIBLE`
* should be updated.
*/
- LATEST = V_1011,
+ LATEST = V_1012,
/**
* The oldest .api.json schema version that is still supported for backwards compatibility.
diff --git a/packages/api-extractor-model/src/model/HeritageType.ts b/packages/api-extractor-model/src/model/HeritageType.ts
index 1efe0f649a64..5332f4a9b487 100644
--- a/packages/api-extractor-model/src/model/HeritageType.ts
+++ b/packages/api-extractor-model/src/model/HeritageType.ts
@@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.
-import type { Excerpt } from '../mixins/Excerpt.js';
+import type { Excerpt, IExcerptTokenRange } from '../mixins/Excerpt.js';
/**
* Represents a type referenced via an "extends" or "implements" heritage clause for a TypeScript class
@@ -38,9 +38,9 @@ export class HeritageType {
*/
public readonly excerpt: Excerpt;
- public readonly typeParameters?: string[];
+ public readonly typeParameters?: IExcerptTokenRange[];
- public constructor(excerpt: Excerpt, typeParameters: string[]) {
+ public constructor(excerpt: Excerpt, typeParameters: IExcerptTokenRange[]) {
this.excerpt = excerpt;
this.typeParameters = typeParameters;
}
diff --git a/packages/api-extractor/src/generators/ApiModelGenerator.ts b/packages/api-extractor/src/generators/ApiModelGenerator.ts
index 94a8f7aa7177..db6f3f759d73 100644
--- a/packages/api-extractor/src/generators/ApiModelGenerator.ts
+++ b/packages/api-extractor/src/generators/ApiModelGenerator.ts
@@ -538,9 +538,6 @@ export class ApiModelGenerator {
if (apiClass === undefined) {
const classDeclaration: ts.ClassDeclaration = astDeclaration.declaration as ts.ClassDeclaration;
- if (name === 'ActionRow') {
- console.dir(classDeclaration.heritageClauses?.[0]?.types[0]?.typeArguments, { depth: 3 });
- }
const nodesToCapture: IExcerptBuilderNodeToCapture[] = [];
@@ -557,9 +554,14 @@ export class ApiModelGenerator {
extendsTokenRange = ExcerptBuilder.createEmptyTokenRangeWithTypeParameters();
if (heritageClause.types.length > 0) {
extendsTokenRange.typeParameters.push(
- ...(heritageClause.types[0]?.typeArguments?.map((typeArgument) =>
- ts.isTypeReferenceNode(typeArgument) ? typeArgument.typeName.getText() : '',
- ) ?? []),
+ ...(heritageClause.types[0]?.typeArguments?.map((typeArgument) => {
+ const typeArgumentTokenRange = ExcerptBuilder.createEmptyTokenRange();
+ if (ts.isTypeReferenceNode(typeArgument)) {
+ nodesToCapture.push({ node: typeArgument, tokenRange: typeArgumentTokenRange });
+ }
+
+ return typeArgumentTokenRange;
+ }) ?? []),
);
nodesToCapture.push({ node: heritageClause.types[0], tokenRange: extendsTokenRange });
}
@@ -568,9 +570,14 @@ export class ApiModelGenerator {
const implementsTokenRange: IExcerptTokenRangeWithTypeParameters =
ExcerptBuilder.createEmptyTokenRangeWithTypeParameters();
implementsTokenRange.typeParameters.push(
- ...(heritageClause.types[0]?.typeArguments?.map((typeArgument) =>
- ts.isTypeReferenceNode(typeArgument) ? typeArgument.typeName.getText() : '',
- ) ?? []),
+ ...(heritageClause.types[0]?.typeArguments?.map((typeArgument) => {
+ const typeArgumentTokenRange = ExcerptBuilder.createEmptyTokenRange();
+ if (ts.isTypeReferenceNode(typeArgument)) {
+ nodesToCapture.push({ node: typeArgument, tokenRange: typeArgumentTokenRange });
+ }
+
+ return typeArgumentTokenRange;
+ }) ?? []),
);
implementsTokenRanges.push(implementsTokenRange);
nodesToCapture.push({ node: heritageType, tokenRange: implementsTokenRange });
@@ -893,9 +900,14 @@ export class ApiModelGenerator {
const extendsTokenRange: IExcerptTokenRangeWithTypeParameters =
ExcerptBuilder.createEmptyTokenRangeWithTypeParameters();
extendsTokenRange.typeParameters.push(
- ...(heritageClause.types[0]?.typeArguments?.map((typeArgument) =>
- ts.isTypeReferenceNode(typeArgument) ? typeArgument.typeName.getText() : '',
- ) ?? []),
+ ...(heritageClause.types[0]?.typeArguments?.map((typeArgument) => {
+ const typeArgumentTokenRange = ExcerptBuilder.createEmptyTokenRange();
+ if (ts.isTypeReferenceNode(typeArgument)) {
+ nodesToCapture.push({ node: typeArgument, tokenRange: typeArgumentTokenRange });
+ }
+
+ return typeArgumentTokenRange;
+ }) ?? []),
);
extendsTokenRanges.push(extendsTokenRange);
nodesToCapture.push({ node: heritageType, tokenRange: extendsTokenRange });
diff --git a/packages/api-extractor/src/generators/ExcerptBuilder.ts b/packages/api-extractor/src/generators/ExcerptBuilder.ts
index 39ea83bf561c..da6b0fd69abb 100644
--- a/packages/api-extractor/src/generators/ExcerptBuilder.ts
+++ b/packages/api-extractor/src/generators/ExcerptBuilder.ts
@@ -176,14 +176,17 @@ export class ExcerptBuilder {
if (span.kind === ts.SyntaxKind.Identifier) {
const name: ts.Identifier = span.node as ts.Identifier;
- if (!ExcerptBuilder._isDeclarationName(name)) {
- canonicalReference = state.referenceGenerator.getDeclarationReferenceForIdentifier(name);
- }
+ canonicalReference = state.referenceGenerator.getDeclarationReferenceForIdentifier(name);
}
if (canonicalReference) {
ExcerptBuilder._appendToken(excerptTokens, ExcerptTokenKind.Reference, span.prefix, canonicalReference);
- } else if (ExcerptBuilder.isPrimitiveKeyword(span.node)) {
+ } else if (
+ ExcerptBuilder.isPrimitiveKeyword(span.node) ||
+ (span.node.kind === ts.SyntaxKind.Identifier &&
+ ((ts.isTypeReferenceNode(span.node.parent) && span.node.parent.typeName === span.node) ||
+ (ts.isTypeParameterDeclaration(span.node.parent) && span.node.parent.name === span.node)))
+ ) {
ExcerptBuilder._appendToken(excerptTokens, ExcerptTokenKind.Reference, span.prefix);
} else {
ExcerptBuilder._appendToken(excerptTokens, ExcerptTokenKind.Content, span.prefix);
@@ -209,7 +212,11 @@ export class ExcerptBuilder {
}
if (span.separator) {
- ExcerptBuilder._appendToken(excerptTokens, ExcerptTokenKind.Content, span.separator);
+ ExcerptBuilder._appendToken(
+ excerptTokens,
+ ExcerptTokenKind.Content,
+ span.separator.replaceAll('\n', '').replaceAll(/\s{2}/g, ' '),
+ );
state.lastAppendedTokenIsSeparator = true;
}
@@ -335,7 +342,7 @@ export class ExcerptBuilder {
}
}
}
- }
+ } /*
private static _isDeclarationName(name: ts.Identifier): boolean {
return ExcerptBuilder._isDeclaration(name.parent) && name.parent.name === name;
@@ -366,5 +373,5 @@ export class ExcerptBuilder {
default:
return false;
}
- }
+ } // */
}
From 2acc03ddb6a2c0ebb8a6b5e60848cd355598546b Mon Sep 17 00:00:00 2001
From: Qjuh <76154676+Qjuh@users.noreply.github.com>
Date: Sat, 11 Nov 2023 11:42:56 +0100
Subject: [PATCH 2/6] fix: correct type param replacement
---
.../src/mixins/ApiItemContainerMixin.ts | 27 ++++++++++++++-----
.../src/generators/ApiModelGenerator.ts | 8 +++---
2 files changed, 23 insertions(+), 12 deletions(-)
diff --git a/packages/api-extractor-model/src/mixins/ApiItemContainerMixin.ts b/packages/api-extractor-model/src/mixins/ApiItemContainerMixin.ts
index 3782457bca38..5e50629daeea 100644
--- a/packages/api-extractor-model/src/mixins/ApiItemContainerMixin.ts
+++ b/packages/api-extractor-model/src/mixins/ApiItemContainerMixin.ts
@@ -42,9 +42,13 @@ export interface IApiItemContainerJson extends IApiItemJson {
preserveMemberOrder?: boolean;
}
+interface ExcerptTokenRangeInDeclaredItem {
+ item: ApiDeclaredItem;
+ range: IExcerptTokenRange;
+}
interface IMappedTypeParameters {
item: ApiItem;
- mappedTypeParameters: Map;
+ mappedTypeParameters: Map;
}
const _members: unique symbol = Symbol('ApiItemContainerMixin._members');
@@ -349,8 +353,11 @@ export function ApiItemContainerMixin(
member.serializeInto(jsonObject);
const excerptTokens = (jsonObject as IApiDeclaredItemJson).excerptTokens.map((token) => {
let x: ExcerptToken | undefined;
- if (typeParams.has(token.text) && next?.item instanceof ApiDeclaredItem)
- x = (member as ApiDeclaredItem).excerptTokens[typeParams.get(token.text)!.startIndex];
+ if (typeParams.has(token.text) && next?.item instanceof ApiDeclaredItem) {
+ const originalValue = typeParams.get(token.text)!;
+ x = originalValue.item.excerptTokens[originalValue.range.startIndex];
+ }
+
const excerptToken: IExcerptToken = x ? { kind: x.kind, text: x.text } : token;
if (x?.canonicalReference !== undefined) {
excerptToken.canonicalReference = x.canonicalReference.toString();
@@ -470,14 +477,20 @@ export function ApiItemContainerMixin(
continue;
}
- const mappedTypeParameters: Map = new Map();
+ const mappedTypeParameters: Map = new Map();
if (
(apiItem.kind === ApiItemKind.Class || apiItem.kind === ApiItemKind.Interface) &&
next.item.kind === ApiItemKind.Class
) {
- for (const [index, typeParameter] of extendsType.typeParameters?.entries() ?? []) {
- const key = (apiItem as ApiClass | ApiInterface).typeParameters[index]?.name ?? '';
- mappedTypeParameters.set(key, typeParameter);
+ for (const [index, key] of (apiItem as ApiClass | ApiInterface).typeParameters.entries() ?? []) {
+ const typeParameter = extendsType.typeParameters?.[index];
+ if (typeParameter)
+ mappedTypeParameters.set(key.name, { item: next.item as ApiDeclaredItem, range: typeParameter });
+ else if (key.defaultTypeExcerpt)
+ mappedTypeParameters.set(key.name, {
+ item: apiItem as ApiDeclaredItem,
+ range: key.defaultTypeExcerpt.tokenRange,
+ });
}
}
diff --git a/packages/api-extractor/src/generators/ApiModelGenerator.ts b/packages/api-extractor/src/generators/ApiModelGenerator.ts
index db6f3f759d73..dc2d0b0122b7 100644
--- a/packages/api-extractor/src/generators/ApiModelGenerator.ts
+++ b/packages/api-extractor/src/generators/ApiModelGenerator.ts
@@ -556,9 +556,7 @@ export class ApiModelGenerator {
extendsTokenRange.typeParameters.push(
...(heritageClause.types[0]?.typeArguments?.map((typeArgument) => {
const typeArgumentTokenRange = ExcerptBuilder.createEmptyTokenRange();
- if (ts.isTypeReferenceNode(typeArgument)) {
- nodesToCapture.push({ node: typeArgument, tokenRange: typeArgumentTokenRange });
- }
+ nodesToCapture.push({ node: typeArgument, tokenRange: typeArgumentTokenRange });
return typeArgumentTokenRange;
}) ?? []),
@@ -570,7 +568,7 @@ export class ApiModelGenerator {
const implementsTokenRange: IExcerptTokenRangeWithTypeParameters =
ExcerptBuilder.createEmptyTokenRangeWithTypeParameters();
implementsTokenRange.typeParameters.push(
- ...(heritageClause.types[0]?.typeArguments?.map((typeArgument) => {
+ ...(heritageType.typeArguments?.map((typeArgument) => {
const typeArgumentTokenRange = ExcerptBuilder.createEmptyTokenRange();
if (ts.isTypeReferenceNode(typeArgument)) {
nodesToCapture.push({ node: typeArgument, tokenRange: typeArgumentTokenRange });
@@ -900,7 +898,7 @@ export class ApiModelGenerator {
const extendsTokenRange: IExcerptTokenRangeWithTypeParameters =
ExcerptBuilder.createEmptyTokenRangeWithTypeParameters();
extendsTokenRange.typeParameters.push(
- ...(heritageClause.types[0]?.typeArguments?.map((typeArgument) => {
+ ...(heritageType.typeArguments?.map((typeArgument) => {
const typeArgumentTokenRange = ExcerptBuilder.createEmptyTokenRange();
if (ts.isTypeReferenceNode(typeArgument)) {
nodesToCapture.push({ node: typeArgument, tokenRange: typeArgumentTokenRange });
From fe899a871409e01af82875f70ffcdbcbdf0416bf Mon Sep 17 00:00:00 2001
From: Qjuh <76154676+Qjuh@users.noreply.github.com>
Date: Sun, 12 Nov 2023 12:15:47 +0100
Subject: [PATCH 3/6] fix: ae config, link builtin in summary, `: | T` => `:
T`, mainlib tsdoc
---
api-extractor.json | 78 ++++++++++---------
.../components/documentation/tsdoc/TSDoc.tsx | 26 ++++++-
.../api-extractor/config/api-extractor.json | 4 +-
.../api-extractor/src/collector/Collector.ts | 2 +-
.../src/generators/ApiModelGenerator.ts | 27 ++++---
.../src/generators/ExcerptBuilder.ts | 27 +++++--
packages/discord.js/typings/index.d.ts | 68 ++++++++--------
7 files changed, 135 insertions(+), 97 deletions(-)
diff --git a/api-extractor.json b/api-extractor.json
index 736568c70792..78b15baef98b 100644
--- a/api-extractor.json
+++ b/api-extractor.json
@@ -89,48 +89,50 @@
* DEFAULT VALUE: no overrideTsconfig section
*/
"overrideTsconfig": {
- // Type Checking
- "allowUnreachableCode": false,
- "allowUnusedLabels": false,
- "exactOptionalPropertyTypes": true,
- "noFallthroughCasesInSwitch": true,
- "noImplicitOverride": true,
- "noImplicitReturns": true,
- "noPropertyAccessFromIndexSignature": false,
- "noUncheckedIndexedAccess": true,
- "noUnusedLocals": true,
- "noUnusedParameters": true,
- "strict": true,
+ "compilerOptions": {
+ // Type Checking
+ "allowUnreachableCode": false,
+ "allowUnusedLabels": false,
+ "exactOptionalPropertyTypes": true,
+ "noFallthroughCasesInSwitch": true,
+ "noImplicitOverride": true,
+ "noImplicitReturns": true,
+ "noPropertyAccessFromIndexSignature": false,
+ "noUncheckedIndexedAccess": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "strict": true,
- // Modules
- "allowArbitraryExtensions": false,
- "allowImportingTsExtensions": false,
- "module": "ESNext",
- "moduleResolution": "node",
- "resolveJsonModule": true,
- "resolvePackageJsonExports": false,
- "resolvePackageJsonImports": false,
+ // Modules
+ "allowArbitraryExtensions": false,
+ "allowImportingTsExtensions": false,
+ "module": "ESNext",
+ "moduleResolution": "nodenext",
+ "resolveJsonModule": true,
+ "resolvePackageJsonExports": false,
+ "resolvePackageJsonImports": false,
- // Emit
- "declaration": true,
- "declarationMap": true,
- "importHelpers": false,
- "newLine": "lf",
- "noEmitHelpers": true,
- "outDir": "dist",
- "removeComments": false,
- "sourceMap": true,
+ // Emit
+ "declaration": true,
+ "declarationMap": true,
+ "importHelpers": false,
+ "newLine": "lf",
+ "noEmitHelpers": true,
+ "outDir": "dist",
+ "removeComments": false,
+ "sourceMap": true,
- // Interop Constraints
- "esModuleInterop": false,
- "forceConsistentCasingInFileNames": true,
- "isolatedModules": true,
+ // Interop Constraints
+ "esModuleInterop": false,
+ "forceConsistentCasingInFileNames": true,
+ "isolatedModules": true,
- // Language and Environment
- "experimentalDecorators": true,
- "lib": ["ESNext"],
- "target": "ES2022",
- "useDefineForClassFields": true
+ // Language and Environment
+ "experimentalDecorators": true,
+ "lib": ["ESNext"],
+ "target": "ES2022",
+ "useDefineForClassFields": true
+ }
}
/**
* This option causes the compiler to be invoked with the --skipLibCheck option. This option is not recommended
diff --git a/apps/website/src/components/documentation/tsdoc/TSDoc.tsx b/apps/website/src/components/documentation/tsdoc/TSDoc.tsx
index 3572ad128ce7..7bd83eebfd52 100644
--- a/apps/website/src/components/documentation/tsdoc/TSDoc.tsx
+++ b/apps/website/src/components/documentation/tsdoc/TSDoc.tsx
@@ -4,6 +4,8 @@ import { DocNodeKind, StandardTags } from '@microsoft/tsdoc';
import type { Route } from 'next';
import Link from 'next/link';
import { Fragment, useCallback, type ReactNode } from 'react';
+import { DocumentationLink } from '~/components/DocumentationLink';
+import { BuiltinDocumentationLinks } from '~/util/builtinDocumentationLinks';
import { ItemLink } from '../../ItemLink';
import { SyntaxHighlighter } from '../../SyntaxHighlighter';
import { resolveItemURI } from '../util';
@@ -12,6 +14,7 @@ import { DefaultValueBlock, DeprecatedBlock, ExampleBlock, RemarksBlock, Returns
export function TSDoc({ item, tsdoc }: { readonly item: ApiItem; readonly tsdoc: DocNode }): JSX.Element {
const createNode = useCallback(
(tsdoc: DocNode, idx?: number): ReactNode => {
+ // console.log(item.displayName, DocNodeKind[tsdoc.kind]);
switch (tsdoc.kind) {
case DocNodeKind.PlainText:
return (
@@ -32,10 +35,24 @@ export function TSDoc({ item, tsdoc }: { readonly item: ApiItem; readonly tsdoc:
const { codeDestination, urlDestination, linkText } = tsdoc as DocLinkTag;
if (codeDestination) {
- // TODO: Real fix in api-extractor needed
- const currentItem = item.getAssociatedPackage();
- const foundItem = item.getAssociatedModel()?.resolveDeclarationReference(codeDestination, currentItem)
- .resolvedApiItem;
+ if (
+ !codeDestination.importPath &&
+ !codeDestination.packageName &&
+ codeDestination.memberReferences.length === 1 &&
+ codeDestination.memberReferences[0]?.memberIdentifier &&
+ codeDestination.memberReferences[0].memberIdentifier?.identifier in BuiltinDocumentationLinks
+ ) {
+ const typeName = codeDestination.memberReferences[0]?.memberIdentifier?.identifier;
+ const href = BuiltinDocumentationLinks[typeName as keyof typeof BuiltinDocumentationLinks];
+ return (
+
+ {typeName}
+
+ );
+ }
+
+ const declarationReference = item.getAssociatedModel()?.resolveDeclarationReference(codeDestination, item);
+ const foundItem = declarationReference.resolvedApiItem;
if (!foundItem) return null;
@@ -44,6 +61,7 @@ export function TSDoc({ item, tsdoc }: { readonly item: ApiItem; readonly tsdoc:
className="rounded font-mono text-blurple outline-none focus:ring focus:ring-width-2 focus:ring-blurple"
itemURI={resolveItemURI(foundItem)}
key={idx}
+ packageName={item.getAssociatedPackage()?.displayName.replace('@discordjs/', '')}
>
{linkText ?? foundItem.displayName}
diff --git a/packages/api-extractor/config/api-extractor.json b/packages/api-extractor/config/api-extractor.json
index c4d10dfdc8cb..58691092e178 100644
--- a/packages/api-extractor/config/api-extractor.json
+++ b/packages/api-extractor/config/api-extractor.json
@@ -5,12 +5,12 @@
"apiReport": {
"enabled": true,
- "reportFolder": "../../../common/reviews/api"
+ "reportFolder": "/docs/review"
},
"docModel": {
"enabled": true,
- "apiJsonFilePath": "../../../common/temp/api/.api.json"
+ "apiJsonFilePath": "/docs/.api.json"
},
"dtsRollup": {
diff --git a/packages/api-extractor/src/collector/Collector.ts b/packages/api-extractor/src/collector/Collector.ts
index 278b65edf545..11dcf18617e4 100644
--- a/packages/api-extractor/src/collector/Collector.ts
+++ b/packages/api-extractor/src/collector/Collector.ts
@@ -4,7 +4,7 @@
import { ReleaseTag } from '@discordjs/api-extractor-model';
import * as tsdoc from '@microsoft/tsdoc';
import { PackageJsonLookup, Sort, InternalError } from '@rushstack/node-core-library';
-import * as ts from 'typescript';
+import ts from 'typescript';
import { PackageDocComment } from '../aedoc/PackageDocComment.js';
import type { AstDeclaration } from '../analyzer/AstDeclaration.js';
import type { AstEntity } from '../analyzer/AstEntity.js';
diff --git a/packages/api-extractor/src/generators/ApiModelGenerator.ts b/packages/api-extractor/src/generators/ApiModelGenerator.ts
index dc2d0b0122b7..8863391a533f 100644
--- a/packages/api-extractor/src/generators/ApiModelGenerator.ts
+++ b/packages/api-extractor/src/generators/ApiModelGenerator.ts
@@ -36,7 +36,6 @@ import {
Navigation,
} from '@discordjs/api-extractor-model';
import type * as tsdoc from '@microsoft/tsdoc';
-import { TSDocParser } from '@microsoft/tsdoc';
import { DeclarationReference } from '@microsoft/tsdoc/lib-commonjs/beta/DeclarationReference.js';
import { JsonFile, Path } from '@rushstack/node-core-library';
import * as ts from 'typescript';
@@ -220,12 +219,16 @@ export class ApiModelGenerator {
private readonly _apiModel: ApiModel;
+ private readonly _tsDocParser: tsdoc.TSDocParser;
+
private readonly _referenceGenerator: DeclarationReferenceGenerator;
public constructor(collector: Collector) {
this._collector = collector;
this._apiModel = new ApiModel();
this._referenceGenerator = new DeclarationReferenceGenerator(collector);
+ // @ts-expect-error we reuse the private tsdocParser from collector here
+ this._tsDocParser = collector._tsdocParser;
}
public get apiModel(): ApiModel {
@@ -500,7 +503,7 @@ export class ApiModelGenerator {
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, nodesToCapture);
const apiItemMetadata: ApiItemMetadata = this._collector.fetchApiItemMetadata(astDeclaration);
const docComment: tsdoc.DocComment | undefined = parent?.construct
- ? new TSDocParser().parseString(
+ ? this._tsDocParser.parseString(
`/*+\n * ${fixLinkTags(parent.construct.description)}\n${
parent.construct.params
?.map((param) => ` * @param ${param.name} - ${fixLinkTags(param.description)}\n`)
@@ -586,7 +589,7 @@ export class ApiModelGenerator {
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, nodesToCapture);
const apiItemMetadata: ApiItemMetadata = this._collector.fetchApiItemMetadata(astDeclaration);
const docComment: tsdoc.DocComment | undefined = jsDoc
- ? new TSDocParser().parseString(
+ ? this._tsDocParser.parseString(
`/**\n * ${fixLinkTags(jsDoc.description)}\n${jsDoc.see?.map((see) => ` * @see ${see}\n`).join('') ?? ''}${
jsDoc.deprecated
? ` * @deprecated ${
@@ -658,7 +661,7 @@ export class ApiModelGenerator {
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, nodesToCapture);
const apiItemMetadata: ApiItemMetadata = this._collector.fetchApiItemMetadata(astDeclaration);
const docComment: tsdoc.DocComment | undefined = parent?.construct
- ? new TSDocParser().parseString(
+ ? this._tsDocParser.parseString(
`/*+\n * ${fixLinkTags(parent.construct.description)}\n${
parent.construct.params
?.map((param) => ` * @param ${param.name} - ${fixLinkTags(param.description)}\n`)
@@ -789,7 +792,7 @@ export class ApiModelGenerator {
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, nodesToCapture);
const apiItemMetadata: ApiItemMetadata = this._collector.fetchApiItemMetadata(astDeclaration);
const docComment: tsdoc.DocComment | undefined = jsDoc
- ? new TSDocParser().parseString(
+ ? this._tsDocParser.parseString(
`/**\n * ${fixLinkTags(jsDoc.description)}\n${
jsDoc.params?.map((param) => ` * @param ${param.name} - ${fixLinkTags(param.description)}\n`).join('') ??
''
@@ -916,7 +919,7 @@ export class ApiModelGenerator {
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, nodesToCapture);
const apiItemMetadata: ApiItemMetadata = this._collector.fetchApiItemMetadata(astDeclaration);
const docComment: tsdoc.DocComment | undefined = jsDoc
- ? new TSDocParser().parseString(
+ ? this._tsDocParser.parseString(
`/**\n * ${fixLinkTags(jsDoc.description)}\n${jsDoc.see?.map((see) => ` * @see ${see}\n`).join('') ?? ''}${
jsDoc.deprecated
? ` * @deprecated ${
@@ -980,7 +983,7 @@ export class ApiModelGenerator {
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, nodesToCapture);
const apiItemMetadata: ApiItemMetadata = this._collector.fetchApiItemMetadata(astDeclaration);
const docComment: tsdoc.DocComment | undefined = jsDoc
- ? new TSDocParser().parseString(
+ ? this._tsDocParser.parseString(
`/**\n * ${fixLinkTags(jsDoc.description)}\n${
jsDoc.params?.map((param) => ` * @param ${param.name} - ${fixLinkTags(param.description)}\n`).join('') ??
''
@@ -1058,7 +1061,7 @@ export class ApiModelGenerator {
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, nodesToCapture);
const apiItemMetadata: ApiItemMetadata = this._collector.fetchApiItemMetadata(astDeclaration);
const docComment: tsdoc.DocComment | undefined = jsDoc
- ? new TSDocParser().parseString(
+ ? this._tsDocParser.parseString(
`/**\n * ${fixLinkTags(jsDoc.description)}\n${
jsDoc.params?.map((param) => ` * @param ${param.name} - ${fixLinkTags(param.description)}\n`).join('') ??
''
@@ -1166,7 +1169,7 @@ export class ApiModelGenerator {
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, nodesToCapture);
const apiItemMetadata: ApiItemMetadata = this._collector.fetchApiItemMetadata(astDeclaration);
const docComment: tsdoc.DocComment | undefined = jsDoc
- ? new TSDocParser().parseString(
+ ? this._tsDocParser.parseString(
`/**\n * ${fixLinkTags(jsDoc.description)}\n${
'see' in jsDoc ? jsDoc.see.map((see) => ` * @see ${see}\n`).join('') : ''
}${'readonly' in jsDoc && jsDoc.readonly ? ' * @readonly\n' : ''}${
@@ -1229,7 +1232,7 @@ export class ApiModelGenerator {
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, nodesToCapture);
const apiItemMetadata: ApiItemMetadata = this._collector.fetchApiItemMetadata(astDeclaration);
const docComment: tsdoc.DocComment | undefined = jsDoc
- ? new TSDocParser().parseString(
+ ? this._tsDocParser.parseString(
`/**\n * ${fixLinkTags(jsDoc.description)}\n${
'see' in jsDoc ? jsDoc.see.map((see) => ` * @see ${see}\n`).join('') : ''
}${'readonly' in jsDoc && jsDoc.readonly ? ' * @readonly\n' : ''}${
@@ -1290,7 +1293,7 @@ export class ApiModelGenerator {
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, nodesToCapture);
const apiItemMetadata: ApiItemMetadata = this._collector.fetchApiItemMetadata(astDeclaration);
const docComment: tsdoc.DocComment | undefined = jsDoc
- ? new TSDocParser().parseString(
+ ? this._tsDocParser.parseString(
`/**\n * ${fixLinkTags(jsDoc.description) ?? ''}\n${
'params' in jsDoc
? jsDoc.params.map((param) => ` * @param ${param.name} - ${fixLinkTags(param.description)}\n`).join('')
@@ -1425,7 +1428,7 @@ export class ApiModelGenerator {
});
}
- const docComment: tsdoc.DocComment | undefined = new TSDocParser().parseString(
+ const docComment: tsdoc.DocComment | undefined = this._tsDocParser.parseString(
`/**\n * ${fixLinkTags(jsDoc.description)}\n${
jsDoc.params?.map((param) => ` * @param ${param.name} - ${fixLinkTags(param.description)}\n`).join('') ?? ''
}${'see' in jsDoc ? jsDoc.see.map((see) => ` * @see ${see}\n`).join('') : ''}${
diff --git a/packages/api-extractor/src/generators/ExcerptBuilder.ts b/packages/api-extractor/src/generators/ExcerptBuilder.ts
index da6b0fd69abb..c991b2adbc28 100644
--- a/packages/api-extractor/src/generators/ExcerptBuilder.ts
+++ b/packages/api-extractor/src/generators/ExcerptBuilder.ts
@@ -135,7 +135,7 @@ export class ExcerptBuilder {
return { startIndex: 0, endIndex: 0, typeParameters: [] };
}
- public static isPrimitiveKeyword(node: ts.Node): boolean {
+ private static _isPrimitiveKeyword(node: ts.Node): boolean {
switch (node.kind) {
case ts.SyntaxKind.AnyKeyword:
case ts.SyntaxKind.BigIntKeyword:
@@ -156,6 +156,15 @@ export class ExcerptBuilder {
}
}
+ private static _isRedundantBarAfterColon(span: Span) {
+ return (
+ span.kind === ts.SyntaxKind.BarToken &&
+ span.previousSibling === undefined &&
+ (span.parent?.parent?.previousSibling?.kind === ts.SyntaxKind.LessThanToken ||
+ span.parent?.parent?.previousSibling?.kind === ts.SyntaxKind.ColonToken)
+ );
+ }
+
private static _buildSpan(excerptTokens: IExcerptToken[], span: Span, state: IBuildSpanState): boolean {
if (span.kind === ts.SyntaxKind.JSDocComment) {
// Discard any comments
@@ -174,21 +183,21 @@ export class ExcerptBuilder {
if (span.prefix) {
let canonicalReference: DeclarationReference | undefined;
- if (span.kind === ts.SyntaxKind.Identifier) {
- const name: ts.Identifier = span.node as ts.Identifier;
+ if (ts.isIdentifier(span.node)) {
+ const name: ts.Identifier = span.node;
canonicalReference = state.referenceGenerator.getDeclarationReferenceForIdentifier(name);
}
if (canonicalReference) {
ExcerptBuilder._appendToken(excerptTokens, ExcerptTokenKind.Reference, span.prefix, canonicalReference);
} else if (
- ExcerptBuilder.isPrimitiveKeyword(span.node) ||
- (span.node.kind === ts.SyntaxKind.Identifier &&
+ ExcerptBuilder._isPrimitiveKeyword(span.node) ||
+ (ts.isIdentifier(span.node) &&
((ts.isTypeReferenceNode(span.node.parent) && span.node.parent.typeName === span.node) ||
(ts.isTypeParameterDeclaration(span.node.parent) && span.node.parent.name === span.node)))
) {
ExcerptBuilder._appendToken(excerptTokens, ExcerptTokenKind.Reference, span.prefix);
- } else {
+ } else if (!ExcerptBuilder._isRedundantBarAfterColon(span)) {
ExcerptBuilder._appendToken(excerptTokens, ExcerptTokenKind.Content, span.prefix);
}
@@ -313,6 +322,12 @@ export class ExcerptBuilder {
!startOrEndIndices.has(currentIndex)
) {
prevToken.text += currentToken.text;
+ // Remove BarTokens from excerpts if they immediately follow a LessThanToken, e.g. `Promise< | Something>`
+ // would become `Promise`
+ if (/<\s*\|/.test(prevToken.text)) {
+ prevToken.text = prevToken.text.replace(/<\s*\|\s*/, '<');
+ }
+
mergeCount = 1;
} else {
// Otherwise, no merging can occur here. Continue to the next index.
diff --git a/packages/discord.js/typings/index.d.ts b/packages/discord.js/typings/index.d.ts
index 876cd8384a06..3f0d67b68e0b 100644
--- a/packages/discord.js/typings/index.d.ts
+++ b/packages/discord.js/typings/index.d.ts
@@ -986,7 +986,7 @@ export class Client extends BaseClient {
public fetchVoiceRegions(): Promise>;
public fetchSticker(id: Snowflake): Promise;
public fetchStickerPacks(): Promise>;
- /** @deprecated Use {@link fetchStickerPacks} instead. */
+ /** @deprecated Use {@link Client#fetchStickerPacks} instead. */
public fetchPremiumStickerPacks(): ReturnType;
public fetchWebhook(id: Snowflake, token?: string): Promise;
public fetchGuildWidget(guild: GuildResolvable): Promise;
@@ -1853,7 +1853,7 @@ export class BaseInteraction extends Base
public isMessageContextMenuCommand(): this is MessageContextMenuCommandInteraction;
public isModalSubmit(): this is ModalSubmitInteraction;
public isUserContextMenuCommand(): this is UserContextMenuCommandInteraction;
- /** @deprecated Use {@link isStringSelectMenu} instead. */
+ /** @deprecated Use {@link BaseInteraction#isStringSelectMenu} instead. */
public isSelectMenu(): this is StringSelectMenuInteraction;
public isAnySelectMenu(): this is AnySelectMenuInteraction;
public isStringSelectMenu(): this is StringSelectMenuInteraction;
@@ -1934,12 +1934,12 @@ export class Invite extends Base {
public toJSON(): unknown;
public toString(): string;
public static InvitesPattern: RegExp;
- /** @deprecated */
+ /** @deprecated Public Stage Instances don't exist anymore */
public stageInstance: InviteStageInstance | null;
public guildScheduledEvent: GuildScheduledEvent | null;
}
-/** @deprecated */
+/** @deprecated Public Stage Instances don't exist anymore */
export class InviteStageInstance extends Base {
private constructor(client: Client, data: RawInviteStageInstance, channelId: Snowflake, guildId: Snowflake);
public channelId: Snowflake;
@@ -3018,7 +3018,7 @@ export class TeamMember extends Base {
private constructor(team: Team, data: RawTeamMemberData);
public team: Team;
public get id(): Snowflake;
- /** @deprecated Use {@link role} instead. */
+ /** @deprecated Use {@link TeamMember#role} instead. */
public permissions: string[];
public membershipState: TeamMemberMembershipState;
public user: User;
@@ -3581,24 +3581,24 @@ export enum DiscordjsErrorCodes {
TokenMissing = 'TokenMissing',
ApplicationCommandPermissionsTokenMissing = 'ApplicationCommandPermissionsTokenMissing',
- /** @deprecated */
+ /** @deprecated ws errors are now handled in `@discordjs/ws` */
WSCloseRequested = 'WSCloseRequested',
- /** @deprecated */
+ /** @deprecated ws errors are now handled in `@discordjs/ws` */
WSConnectionExists = 'WSConnectionExists',
- /** @deprecated */
+ /** @deprecated ws errors are now handled in `@discordjs/ws` */
WSNotOpen = 'WSNotOpen',
- /** @deprecated */
+ /** @deprecated was never used */
ManagerDestroyed = 'ManagerDestroyed',
BitFieldInvalid = 'BitFieldInvalid',
- /** @deprecated */
+ /** @deprecated was never used */
ShardingInvalid = 'ShardingInvalid',
- /** @deprecated */
+ /** @deprecated was never used */
ShardingRequired = 'ShardingRequired',
- /** @deprecated */
+ /** @deprecated was never used */
InvalidIntents = 'InvalidIntents',
- /** @deprecated */
+ /** @deprecated was never used */
DisallowedIntents = 'DisallowedIntents',
ShardingNoShards = 'ShardingNoShards',
ShardingInProcess = 'ShardingInProcess',
@@ -3618,29 +3618,29 @@ export enum DiscordjsErrorCodes {
InviteOptionsMissingChannel = 'InviteOptionsMissingChannel',
- /** @deprecated */
+ /** @deprecated was never used */
ButtonLabel = 'ButtonLabel',
- /** @deprecated */
+ /** @deprecated was never used */
ButtonURL = 'ButtonURL',
- /** @deprecated */
+ /** @deprecated was never used */
ButtonCustomId = 'ButtonCustomId',
- /** @deprecated */
+ /** @deprecated was never used */
SelectMenuCustomId = 'SelectMenuCustomId',
- /** @deprecated */
+ /** @deprecated was never used */
SelectMenuPlaceholder = 'SelectMenuPlaceholder',
- /** @deprecated */
+ /** @deprecated was never used */
SelectOptionLabel = 'SelectOptionLabel',
- /** @deprecated */
+ /** @deprecated was never used */
SelectOptionValue = 'SelectOptionValue',
- /** @deprecated */
+ /** @deprecated was never used */
SelectOptionDescription = 'SelectOptionDescription',
InteractionCollectorError = 'InteractionCollectorError',
FileNotFound = 'FileNotFound',
- /** @deprecated */
+ /** @deprecated was never used */
UserBannerNotFetched = 'UserBannerNotFetched',
UserNoDMChannel = 'UserNoDMChannel',
@@ -3651,16 +3651,16 @@ export enum DiscordjsErrorCodes {
ReqResourceType = 'ReqResourceType',
- /** @deprecated */
+ /** @deprecated was never used */
ImageFormat = 'ImageFormat',
- /** @deprecated */
+ /** @deprecated was never used */
ImageSize = 'ImageSize',
MessageBulkDeleteType = 'MessageBulkDeleteType',
MessageNonceType = 'MessageNonceType',
MessageContentType = 'MessageContentType',
- /** @deprecated */
+ /** @deprecated was never used */
SplitMaxLen = 'SplitMaxLen',
BanResolveId = 'BanResolveId',
@@ -3696,14 +3696,14 @@ export enum DiscordjsErrorCodes {
EmojiType = 'EmojiType',
EmojiManaged = 'EmojiManaged',
MissingManageGuildExpressionsPermission = 'MissingManageGuildExpressionsPermission',
- /** @deprecated Use {@link MissingManageGuildExpressionsPermission} instead. */
+ /** @deprecated Use {@link DiscordjsErrorCodes.MissingManageGuildExpressionsPermission} instead. */
MissingManageEmojisAndStickersPermission = 'MissingManageEmojisAndStickersPermission',
NotGuildSticker = 'NotGuildSticker',
ReactionResolveUser = 'ReactionResolveUser',
- /** @deprecated */
+ /** @deprecated Not used anymore since the introduction of `GUILD_WEB_PAGE_VANITY_URL` feature */
VanityURL = 'VanityURL',
InviteResolveCode = 'InviteResolveCode',
@@ -3720,7 +3720,7 @@ export enum DiscordjsErrorCodes {
InteractionAlreadyReplied = 'InteractionAlreadyReplied',
InteractionNotReplied = 'InteractionNotReplied',
- /** @deprecated */
+ /** @deprecated Not used anymore since ephemeral replies can now be deleted without issue */
InteractionEphemeralReplied = 'InteractionEphemeralReplied',
CommandInteractionOptionNotFound = 'CommandInteractionOptionNotFound',
@@ -4747,7 +4747,7 @@ export interface AwaitReactionsOptions extends ReactionCollectorOptions {
}
export interface BanOptions {
- /** @deprecated Use {@link deleteMessageSeconds} instead. */
+ /** @deprecated Use {@link BanOptions#deleteMessageSeconds} instead. */
deleteMessageDays?: number;
deleteMessageSeconds?: number;
reason?: string;
@@ -4947,7 +4947,7 @@ export interface ClientEvents {
typingStart: [typing: Typing];
userUpdate: [oldUser: User | PartialUser, newUser: User];
voiceStateUpdate: [oldState: VoiceState, newState: VoiceState];
- /** @deprecated Use {@link webhooksUpdate} instead. */
+ /** @deprecated Use {@link ClientEvents#webhooksUpdate} instead. */
webhookUpdate: ClientEvents['webhooksUpdate'];
webhooksUpdate: [channel: TextChannel | NewsChannel | VoiceChannel | ForumChannel | MediaChannel];
interactionCreate: [interaction: Interaction];
@@ -5007,10 +5007,10 @@ export interface ClientUserEditOptions {
}
export interface CloseEvent {
- /** @deprecated */
+ /** @deprecated not used anymore since using {@link @discordjs/ws!WebSocketManager:class#} internally */
wasClean: boolean;
code: number;
- /** @deprecated */
+ /** @deprecated not used anymore since using {@link @discordjs/ws!WebSocketManager:class#} internally */
reason: string;
}
@@ -5336,11 +5336,11 @@ export interface FetchGuildScheduledEventSubscribersOptions {
withMember?: boolean;
}
-interface FetchInviteOptions extends BaseFetchOptions {
+export interface FetchInviteOptions extends BaseFetchOptions {
code: string;
}
-interface FetchInvitesOptions {
+export interface FetchInvitesOptions {
channelId?: GuildInvitableChannelResolvable;
cache?: boolean;
}
From 35655221aa025be6e253a1b7f9fb174b52be629c Mon Sep 17 00:00:00 2001
From: Qjuh <76154676+Qjuh@users.noreply.github.com>
Date: Sun, 12 Nov 2023 13:01:41 +0100
Subject: [PATCH 4/6] fix: requested changes and tests
---
apps/website/src/components/documentation/tsdoc/TSDoc.tsx | 3 +--
packages/discord.js/typings/index.d.ts | 4 ++--
2 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/apps/website/src/components/documentation/tsdoc/TSDoc.tsx b/apps/website/src/components/documentation/tsdoc/TSDoc.tsx
index 7bd83eebfd52..686d1cec1fdc 100644
--- a/apps/website/src/components/documentation/tsdoc/TSDoc.tsx
+++ b/apps/website/src/components/documentation/tsdoc/TSDoc.tsx
@@ -14,7 +14,6 @@ import { DefaultValueBlock, DeprecatedBlock, ExampleBlock, RemarksBlock, Returns
export function TSDoc({ item, tsdoc }: { readonly item: ApiItem; readonly tsdoc: DocNode }): JSX.Element {
const createNode = useCallback(
(tsdoc: DocNode, idx?: number): ReactNode => {
- // console.log(item.displayName, DocNodeKind[tsdoc.kind]);
switch (tsdoc.kind) {
case DocNodeKind.PlainText:
return (
@@ -52,7 +51,7 @@ export function TSDoc({ item, tsdoc }: { readonly item: ApiItem; readonly tsdoc:
}
const declarationReference = item.getAssociatedModel()?.resolveDeclarationReference(codeDestination, item);
- const foundItem = declarationReference.resolvedApiItem;
+ const foundItem = declarationReference?.resolvedApiItem;
if (!foundItem) return null;
diff --git a/packages/discord.js/typings/index.d.ts b/packages/discord.js/typings/index.d.ts
index 3f0d67b68e0b..4bde7ec96d78 100644
--- a/packages/discord.js/typings/index.d.ts
+++ b/packages/discord.js/typings/index.d.ts
@@ -5007,10 +5007,10 @@ export interface ClientUserEditOptions {
}
export interface CloseEvent {
- /** @deprecated not used anymore since using {@link @discordjs/ws!WebSocketManager:class#} internally */
+ /** @deprecated Not used anymore since using {@link @discordjs/ws#WebSocketManager} internally */
wasClean: boolean;
code: number;
- /** @deprecated not used anymore since using {@link @discordjs/ws!WebSocketManager:class#} internally */
+ /** @deprecated Not used anymore since using {@link @discordjs/ws#WebSocketManager} internally */
reason: string;
}
From 148e08bc51405291efdc839479f08f8974d6c321 Mon Sep 17 00:00:00 2001
From: Almeida
Date: Sun, 12 Nov 2023 12:34:11 +0000
Subject: [PATCH 5/6] chore: better deprecation messages and code cleanup
---
.../components/documentation/tsdoc/TSDoc.tsx | 6 +--
packages/discord.js/typings/index.d.ts | 42 +++++++++----------
2 files changed, 24 insertions(+), 24 deletions(-)
diff --git a/apps/website/src/components/documentation/tsdoc/TSDoc.tsx b/apps/website/src/components/documentation/tsdoc/TSDoc.tsx
index 686d1cec1fdc..fbddbe3c65e2 100644
--- a/apps/website/src/components/documentation/tsdoc/TSDoc.tsx
+++ b/apps/website/src/components/documentation/tsdoc/TSDoc.tsx
@@ -38,10 +38,10 @@ export function TSDoc({ item, tsdoc }: { readonly item: ApiItem; readonly tsdoc:
!codeDestination.importPath &&
!codeDestination.packageName &&
codeDestination.memberReferences.length === 1 &&
- codeDestination.memberReferences[0]?.memberIdentifier &&
- codeDestination.memberReferences[0].memberIdentifier?.identifier in BuiltinDocumentationLinks
+ codeDestination.memberReferences[0]!.memberIdentifier &&
+ codeDestination.memberReferences[0]!.memberIdentifier.identifier in BuiltinDocumentationLinks
) {
- const typeName = codeDestination.memberReferences[0]?.memberIdentifier?.identifier;
+ const typeName = codeDestination.memberReferences[0]!.memberIdentifier.identifier;
const href = BuiltinDocumentationLinks[typeName as keyof typeof BuiltinDocumentationLinks];
return (
diff --git a/packages/discord.js/typings/index.d.ts b/packages/discord.js/typings/index.d.ts
index 4bde7ec96d78..518964af01d2 100644
--- a/packages/discord.js/typings/index.d.ts
+++ b/packages/discord.js/typings/index.d.ts
@@ -3581,24 +3581,24 @@ export enum DiscordjsErrorCodes {
TokenMissing = 'TokenMissing',
ApplicationCommandPermissionsTokenMissing = 'ApplicationCommandPermissionsTokenMissing',
- /** @deprecated ws errors are now handled in `@discordjs/ws` */
+ /** @deprecated WebSocket errors are now handled in `@discordjs/ws` */
WSCloseRequested = 'WSCloseRequested',
- /** @deprecated ws errors are now handled in `@discordjs/ws` */
+ /** @deprecated WebSocket errors are now handled in `@discordjs/ws` */
WSConnectionExists = 'WSConnectionExists',
- /** @deprecated ws errors are now handled in `@discordjs/ws` */
+ /** @deprecated WebSocket errors are now handled in `@discordjs/ws` */
WSNotOpen = 'WSNotOpen',
- /** @deprecated was never used */
+ /** @deprecated No longer in use */
ManagerDestroyed = 'ManagerDestroyed',
BitFieldInvalid = 'BitFieldInvalid',
- /** @deprecated was never used */
+ /** @deprecated This error is now handled in `@discordjs/ws` */
ShardingInvalid = 'ShardingInvalid',
- /** @deprecated was never used */
+ /** @deprecated This error is now handled in `@discordjs/ws` */
ShardingRequired = 'ShardingRequired',
- /** @deprecated was never used */
+ /** @deprecated This error is now handled in `@discordjs/ws` */
InvalidIntents = 'InvalidIntents',
- /** @deprecated was never used */
+ /** @deprecated This error is now handled in `@discordjs/ws` */
DisallowedIntents = 'DisallowedIntents',
ShardingNoShards = 'ShardingNoShards',
ShardingInProcess = 'ShardingInProcess',
@@ -3618,29 +3618,29 @@ export enum DiscordjsErrorCodes {
InviteOptionsMissingChannel = 'InviteOptionsMissingChannel',
- /** @deprecated was never used */
+ /** @deprecated Button validation errors are now handled in `@discordjs/builders` */
ButtonLabel = 'ButtonLabel',
- /** @deprecated was never used */
+ /** @deprecated Button validation errors are now handled in `@discordjs/builders` */
ButtonURL = 'ButtonURL',
- /** @deprecated was never used */
+ /** @deprecated Button validation errors are now handled in `@discordjs/builders` */
ButtonCustomId = 'ButtonCustomId',
- /** @deprecated was never used */
+ /** @deprecated Select Menu validation errors are now handled in `@discordjs/builders` */
SelectMenuCustomId = 'SelectMenuCustomId',
- /** @deprecated was never used */
+ /** @deprecated Select Menu validation errors are now handled in `@discordjs/builders` */
SelectMenuPlaceholder = 'SelectMenuPlaceholder',
- /** @deprecated was never used */
+ /** @deprecated Select Menu validation errors are now handled in `@discordjs/builders` */
SelectOptionLabel = 'SelectOptionLabel',
- /** @deprecated was never used */
+ /** @deprecated Select Menu validation errors are now handled in `@discordjs/builders` */
SelectOptionValue = 'SelectOptionValue',
- /** @deprecated was never used */
+ /** @deprecated Select Menu validation errors are now handled in `@discordjs/builders` */
SelectOptionDescription = 'SelectOptionDescription',
InteractionCollectorError = 'InteractionCollectorError',
FileNotFound = 'FileNotFound',
- /** @deprecated was never used */
+ /** @deprecated No longer in use */
UserBannerNotFetched = 'UserBannerNotFetched',
UserNoDMChannel = 'UserNoDMChannel',
@@ -3651,16 +3651,16 @@ export enum DiscordjsErrorCodes {
ReqResourceType = 'ReqResourceType',
- /** @deprecated was never used */
+ /** @deprecated This error is now handled in `@discordjs/rest` */
ImageFormat = 'ImageFormat',
- /** @deprecated was never used */
+ /** @deprecated This error is now handled in `@discordjs/rest` */
ImageSize = 'ImageSize',
MessageBulkDeleteType = 'MessageBulkDeleteType',
MessageNonceType = 'MessageNonceType',
MessageContentType = 'MessageContentType',
- /** @deprecated was never used */
+ /** @deprecated No longer in use */
SplitMaxLen = 'SplitMaxLen',
BanResolveId = 'BanResolveId',
@@ -3720,7 +3720,7 @@ export enum DiscordjsErrorCodes {
InteractionAlreadyReplied = 'InteractionAlreadyReplied',
InteractionNotReplied = 'InteractionNotReplied',
- /** @deprecated Not used anymore since ephemeral replies can now be deleted without issue */
+ /** @deprecated Not used anymore since ephemeral replies can now be deleted */
InteractionEphemeralReplied = 'InteractionEphemeralReplied',
CommandInteractionOptionNotFound = 'CommandInteractionOptionNotFound',
From 7a1c20f1a9462040167be1db6424f294eaeda09d Mon Sep 17 00:00:00 2001
From: Qjuh <76154676+Qjuh@users.noreply.github.com>
Date: Sun, 12 Nov 2023 14:55:11 +0100
Subject: [PATCH 6/6] fix: cleanup optional chainings
---
apps/website/src/components/documentation/tsdoc/TSDoc.tsx | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/apps/website/src/components/documentation/tsdoc/TSDoc.tsx b/apps/website/src/components/documentation/tsdoc/TSDoc.tsx
index 686d1cec1fdc..60c58693fc41 100644
--- a/apps/website/src/components/documentation/tsdoc/TSDoc.tsx
+++ b/apps/website/src/components/documentation/tsdoc/TSDoc.tsx
@@ -39,9 +39,9 @@ export function TSDoc({ item, tsdoc }: { readonly item: ApiItem; readonly tsdoc:
!codeDestination.packageName &&
codeDestination.memberReferences.length === 1 &&
codeDestination.memberReferences[0]?.memberIdentifier &&
- codeDestination.memberReferences[0].memberIdentifier?.identifier in BuiltinDocumentationLinks
+ codeDestination.memberReferences[0].memberIdentifier.identifier in BuiltinDocumentationLinks
) {
- const typeName = codeDestination.memberReferences[0]?.memberIdentifier?.identifier;
+ const typeName = codeDestination.memberReferences[0].memberIdentifier.identifier;
const href = BuiltinDocumentationLinks[typeName as keyof typeof BuiltinDocumentationLinks];
return (