From a44ada661f14504b56102e081b1c7108f4d9b06e Mon Sep 17 00:00:00 2001 From: Qjuh <76154676+Qjuh@users.noreply.github.com> Date: Fri, 1 Dec 2023 02:19:07 +0100 Subject: [PATCH] feat(website): show union members of type aliases (#10001) * feat(website): show union members of type aliases * refactor: suggestions from code review * Apply suggestions from code review --------- Co-authored-by: Noel --- .../section/UnionMembersSection.tsx | 36 ++++++++ .../src/components/model/TypeAlias.tsx | 52 +++++++++++- packages/discord.js/typings/index.d.ts | 85 +++++++++---------- 3 files changed, 125 insertions(+), 48 deletions(-) create mode 100644 apps/website/src/components/documentation/section/UnionMembersSection.tsx diff --git a/apps/website/src/components/documentation/section/UnionMembersSection.tsx b/apps/website/src/components/documentation/section/UnionMembersSection.tsx new file mode 100644 index 000000000000..7daa29901658 --- /dev/null +++ b/apps/website/src/components/documentation/section/UnionMembersSection.tsx @@ -0,0 +1,36 @@ +import { Excerpt, type ApiTypeAlias, type ExcerptToken } from '@discordjs/api-extractor-model'; +import { VscSymbolArray } from '@react-icons/all-files/vsc/VscSymbolArray'; +import { useMemo } from 'react'; +import { ExcerptText } from '~/components/ExcerptText'; +import { DocumentationSection } from './DocumentationSection'; + +export type UnionMember = ExcerptToken[]; + +export function UnionMembersSection({ + item, + members, +}: { + readonly item: ApiTypeAlias; + readonly members: UnionMember[]; +}) { + const unionMembers = useMemo( + () => + members.map((member, idx) => ( +
+ + + +
+ )), + [item, members], + ); + + return ( + } padded title="Union Members"> +
{unionMembers}
+
+ ); +} diff --git a/apps/website/src/components/model/TypeAlias.tsx b/apps/website/src/components/model/TypeAlias.tsx index c5bb207a50f7..02d6d3882f9d 100644 --- a/apps/website/src/components/model/TypeAlias.tsx +++ b/apps/website/src/components/model/TypeAlias.tsx @@ -1,10 +1,59 @@ -import type { ApiTypeAlias } from '@discordjs/api-extractor-model'; +import { ExcerptTokenKind, type ApiTypeAlias, ExcerptToken } from '@discordjs/api-extractor-model'; +import { useMemo } from 'react'; import { SyntaxHighlighter } from '../SyntaxHighlighter'; import { Documentation } from '../documentation/Documentation'; import { Header } from '../documentation/Header'; import { SummarySection } from '../documentation/section/SummarySection'; +import { UnionMembersSection } from '../documentation/section/UnionMembersSection'; export function TypeAlias({ item }: { readonly item: ApiTypeAlias }) { + const union = useMemo(() => { + const union: ExcerptToken[][] = []; + let currentUnionMember: ExcerptToken[] = []; + let depth = 0; + for (const token of item.typeExcerpt.spannedTokens) { + if (token.text.includes('?')) { + return []; + } + + if (token.text.includes('<')) { + depth++; + } + + if (token.text.includes('>')) { + depth--; + } + + if (token.text.trim() === '|' && depth === 0) { + if (currentUnionMember.length) { + union.push(currentUnionMember); + currentUnionMember = []; + } + } else if (depth === 0 && token.kind === ExcerptTokenKind.Content && token.text.includes('|')) { + for (const [idx, tokenpart] of token.text.split('|').entries()) { + if (currentUnionMember.length && depth === 0 && idx === 0) { + currentUnionMember.push(new ExcerptToken(ExcerptTokenKind.Content, tokenpart)); + union.push(currentUnionMember); + currentUnionMember = []; + } else if (currentUnionMember.length && depth === 0) { + union.push(currentUnionMember); + currentUnionMember = [new ExcerptToken(ExcerptTokenKind.Content, tokenpart)]; + } else if (tokenpart.length) { + currentUnionMember.push(new ExcerptToken(ExcerptTokenKind.Content, tokenpart)); + } + } + } else { + currentUnionMember.push(token); + } + } + + if (currentUnionMember.length && union.length) { + union.push(currentUnionMember); + } + + return union; + }, [item]); + return (
+ {union.length ? : null} ); } diff --git a/packages/discord.js/typings/index.d.ts b/packages/discord.js/typings/index.d.ts index 5592d6c93606..312f66796f1f 100644 --- a/packages/discord.js/typings/index.d.ts +++ b/packages/discord.js/typings/index.d.ts @@ -859,9 +859,9 @@ export interface IconData { proxyIconURL?: string; } -export type EmbedAuthorData = Omit & IconData; +export interface EmbedAuthorData extends Omit, IconData {} -export type EmbedFooterData = Omit & IconData; +export interface EmbedFooterData extends Omit, IconData {} export interface EmbedAssetData extends Omit { proxyURL?: string; @@ -1989,29 +1989,29 @@ export class LimitedCollection extends Collection { export type MessageComponentType = Exclude; -export type MessageCollectorOptionsParams< +export interface MessageCollectorOptionsParams< ComponentType extends MessageComponentType, Cached extends boolean = boolean, -> = { +> extends MessageComponentCollectorOptions[ComponentType]> { componentType?: ComponentType; -} & MessageComponentCollectorOptions[ComponentType]>; +} -export type MessageChannelCollectorOptionsParams< +export interface MessageChannelCollectorOptionsParams< ComponentType extends MessageComponentType, Cached extends boolean = boolean, -> = { +> extends MessageChannelComponentCollectorOptions[ComponentType]> { componentType?: ComponentType; -} & MessageChannelComponentCollectorOptions[ComponentType]>; +} -export type AwaitMessageCollectorOptionsParams< +export interface AwaitMessageCollectorOptionsParams< ComponentType extends MessageComponentType, Cached extends boolean = boolean, -> = { +> extends Pick< + InteractionCollectorOptions[ComponentType]>, + keyof AwaitMessageComponentOptions + > { componentType?: ComponentType; -} & Pick< - InteractionCollectorOptions[ComponentType]>, - keyof AwaitMessageComponentOptions ->; +} export interface StringMappedInteractionTypes { Button: ButtonInteraction; @@ -2437,7 +2437,9 @@ export interface GuildForumTag { emoji: GuildForumTagEmoji | null; } -export type GuildForumTagData = Partial & { name: string }; +export interface GuildForumTagData extends Partial { + name: string; +} export interface DefaultReactionEmoji { id: Snowflake | null; @@ -3974,7 +3976,7 @@ export class ChannelManager extends CachedManager; } -export type FetchGuildApplicationCommandFetchOptions = Omit; +export interface FetchGuildApplicationCommandFetchOptions extends Omit {} export class GuildApplicationCommandManager extends ApplicationCommandManager { private constructor(guild: Guild, iterable?: Iterable); @@ -4421,7 +4423,7 @@ export interface WebhookFields extends PartialWebhookFields { //#region Typedefs -export type ActivitiesOptions = Omit; +export interface ActivitiesOptions extends Omit {} export interface ActivityOptions { name: string; @@ -4776,22 +4778,16 @@ export interface AutoModerationTriggerMetadata { mentionRaidProtectionEnabled: boolean; } -export type AwaitMessageComponentOptions = Omit< - MessageComponentCollectorOptions, - 'max' | 'maxComponents' | 'maxUsers' ->; +export interface AwaitMessageComponentOptions + extends Omit, 'max' | 'maxComponents' | 'maxUsers'> {} -export type ModalSubmitInteractionCollectorOptions = Omit< - InteractionCollectorOptions, - 'channel' | 'message' | 'guild' | 'interactionType' ->; +export interface ModalSubmitInteractionCollectorOptions + extends Omit, 'channel' | 'message' | 'guild' | 'interactionType'> {} -export type AwaitModalSubmitOptions = Omit< - ModalSubmitInteractionCollectorOptions, - 'max' | 'maxComponents' | 'maxUsers' -> & { +export interface AwaitModalSubmitOptions + extends Omit, 'max' | 'maxComponents' | 'maxUsers'> { time: number; -}; +} export interface AwaitMessagesOptions extends MessageCollectorOptions { errors?: string[]; @@ -5114,14 +5110,14 @@ export interface CommandInteractionResolvedData; } -export type AutocompleteFocusedOption = Pick & { +export interface AutocompleteFocusedOption extends Pick { focused: true; type: | ApplicationCommandOptionType.String | ApplicationCommandOptionType.Integer | ApplicationCommandOptionType.Number; value: string; -}; +} export declare const Colors: { Default: 0x000000; @@ -5913,7 +5909,7 @@ export interface InteractionDeferReplyOptions { fetchReply?: boolean; } -export type InteractionDeferUpdateOptions = Omit; +export interface InteractionDeferUpdateOptions extends Omit {} export interface InteractionReplyOptions extends BaseMessageOptions { tts?: boolean; @@ -6025,15 +6021,11 @@ export type CollectedMessageInteraction = ModalSubmitInteraction >; -export type MessageComponentCollectorOptions = Omit< - InteractionCollectorOptions, - 'channel' | 'message' | 'guild' | 'interactionType' ->; +export interface MessageComponentCollectorOptions + extends Omit, 'channel' | 'message' | 'guild' | 'interactionType'> {} -export type MessageChannelComponentCollectorOptions = Omit< - InteractionCollectorOptions, - 'channel' | 'guild' | 'interactionType' ->; +export interface MessageChannelComponentCollectorOptions + extends Omit, 'channel' | 'guild' | 'interactionType'> {} export interface MessageEvent { data: WebSocketData; @@ -6094,8 +6086,9 @@ export interface MessageCreateOptions extends BaseMessageOptions { >; } -export type GuildForumThreadMessageCreateOptions = BaseMessageOptions & - Pick; +export interface GuildForumThreadMessageCreateOptions + extends BaseMessageOptions, + Pick {} export interface MessageEditAttachmentData { id: Snowflake; @@ -6215,9 +6208,7 @@ export type PermissionResolvable = BitFieldResolvable = ReadonlyArray>; - -export type RecursiveReadonlyArray = ReadonlyArray>; +export interface RecursiveReadonlyArray extends ReadonlyArray> {} export interface PartialRecipient { username: string; @@ -6567,7 +6558,7 @@ export interface WebhookClientDataURL { url: string; } -export type WebhookClientOptions = Pick; +export interface WebhookClientOptions extends Pick {} export interface WebhookDeleteOptions { token?: string;