diff --git a/apps/website/src/components/ParameterNode.tsx b/apps/website/src/components/ParameterNode.tsx index 02f35ec29b83..030e11820e33 100644 --- a/apps/website/src/components/ParameterNode.tsx +++ b/apps/website/src/components/ParameterNode.tsx @@ -29,6 +29,7 @@ export async function ParameterNode({ {description ? : null} {parameter.name} {parameter.isOptional ? '?' : ''}: + {parameter.defaultValue ? ` = ${parameter.defaultValue}` : ''} {description && parameter.description?.length ? (
diff --git a/apps/website/src/components/PropertyNode.tsx b/apps/website/src/components/PropertyNode.tsx index 2bbc31cae0dd..231eacc541c0 100644 --- a/apps/website/src/components/PropertyNode.tsx +++ b/apps/website/src/components/PropertyNode.tsx @@ -51,7 +51,13 @@ export async function PropertyNode({ {property.displayName} - {property.isOptional ? '?' : ''} : + {property.isOptional ? '?' : ''} : {' '} + {property.summary?.defaultValueBlock.length + ? `= ${property.summary.defaultValueBlock.reduce( + (acc: string, def: { kind: string; text: string }) => `${acc}${def.text}`, + '', + )}` + : ''} diff --git a/packages/api-extractor-model/src/mixins/ApiParameterListMixin.ts b/packages/api-extractor-model/src/mixins/ApiParameterListMixin.ts index 5df2f2d4962b..cb4c895eab95 100644 --- a/packages/api-extractor-model/src/mixins/ApiParameterListMixin.ts +++ b/packages/api-extractor-model/src/mixins/ApiParameterListMixin.ts @@ -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( isOptional: Boolean(parameterOptions.isOptional), isRest: Boolean(parameterOptions.isRest), parent: this, + defaultValue: parameterOptions.defaultValue, }); this[_parameters].push(parameter); @@ -171,6 +173,7 @@ export function ApiParameterListMixin( parameterTypeTokenRange: parameter.parameterTypeExcerpt.tokenRange, isOptional: parameter.isOptional, isRest: parameter.isRest, + defaultValue: parameter.defaultValue, }); } diff --git a/packages/api-extractor-model/src/model/ApiPackage.ts b/packages/api-extractor-model/src/model/ApiPackage.ts index fee2211a6770..89f8b4372ca1 100644 --- a/packages/api-extractor-model/src/model/ApiPackage.ts +++ b/packages/api-extractor-model/src/model/ApiPackage.ts @@ -41,6 +41,7 @@ const MinifyJSONMapping = { constraintTokenRange: 'ctr', dependencies: 'dp', defaultTypeTokenRange: 'dtr', + defaultValue: 'dv', docComment: 'd', endIndex: 'en', excerptTokens: 'ex', diff --git a/packages/api-extractor-model/src/model/Deserializer.ts b/packages/api-extractor-model/src/model/Deserializer.ts index fc60ed1c8920..454912626b39 100644 --- a/packages/api-extractor-model/src/model/Deserializer.ts +++ b/packages/api-extractor-model/src/model/Deserializer.ts @@ -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, }; } diff --git a/packages/api-extractor-model/src/model/Parameter.ts b/packages/api-extractor-model/src/model/Parameter.ts index c0d47f0a6432..158ac5222986 100644 --- a/packages/api-extractor-model/src/model/Parameter.ts +++ b/packages/api-extractor-model/src/model/Parameter.ts @@ -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; } /** diff --git a/packages/api-extractor/src/generators/ApiModelGenerator.ts b/packages/api-extractor/src/generators/ApiModelGenerator.ts index c55268815004..19c46fa2b44c 100644 --- a/packages/api-extractor/src/generators/ApiModelGenerator.ts +++ b/packages/api-extractor/src/generators/ApiModelGenerator.ts @@ -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, + 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(/(?[{}])/g, '\\$'); + return input.replaceAll(/(?[@{}])/g, '\\$'); } 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] ?? []); diff --git a/packages/discord.js/src/util/Options.js b/packages/discord.js/src/util/Options.js index 14af76ea692c..aebc63af4d48 100644 --- a/packages/discord.js/src/util/Options.js +++ b/packages/discord.js/src/util/Options.js @@ -26,7 +26,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 @@ -37,7 +37,7 @@ const { version } = require('../../package.json'); * @property {WebSocketManagerOptions} [ws] Options for the WebSocketManager * @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} */ /** diff --git a/packages/discord.js/typings/index.d.ts b/packages/discord.js/typings/index.d.ts index ad512d8ed58b..8a603abefb17 100644 --- a/packages/discord.js/typings/index.d.ts +++ b/packages/discord.js/typings/index.d.ts @@ -5731,7 +5731,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; diff --git a/packages/scripts/src/builtinDocumentationLinks.ts b/packages/scripts/src/builtinDocumentationLinks.ts new file mode 100644 index 000000000000..1cafb2dbfc42 --- /dev/null +++ b/packages/scripts/src/builtinDocumentationLinks.ts @@ -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; diff --git a/packages/scripts/src/generateSplitDocumentation.ts b/packages/scripts/src/generateSplitDocumentation.ts index 6c523a34ef47..ee83a2b6f2b3 100644 --- a/packages/scripts/src/generateSplitDocumentation.ts +++ b/packages/scripts/src/generateSplitDocumentation.ts @@ -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, }; } @@ -534,6 +566,7 @@ function resolveParameters(item: ApiDocumentedItem & ApiParameterListMixin) { isOptional: param.isOptional, isRest: param.isRest, parameterTypeExcerpt: param.parameterTypeExcerpt, + defaultValue: param.defaultValue, }; }); } @@ -553,9 +586,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 +605,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 +660,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 +700,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 +800,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 +898,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), + ), ), }; }