Skip to content

Commit a44ada6

Browse files
QjuhiCrawl
andauthored
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 <[email protected]>
1 parent b229240 commit a44ada6

File tree

3 files changed

+125
-48
lines changed

3 files changed

+125
-48
lines changed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { Excerpt, type ApiTypeAlias, type ExcerptToken } from '@discordjs/api-extractor-model';
2+
import { VscSymbolArray } from '@react-icons/all-files/vsc/VscSymbolArray';
3+
import { useMemo } from 'react';
4+
import { ExcerptText } from '~/components/ExcerptText';
5+
import { DocumentationSection } from './DocumentationSection';
6+
7+
export type UnionMember = ExcerptToken[];
8+
9+
export function UnionMembersSection({
10+
item,
11+
members,
12+
}: {
13+
readonly item: ApiTypeAlias;
14+
readonly members: UnionMember[];
15+
}) {
16+
const unionMembers = useMemo(
17+
() =>
18+
members.map((member, idx) => (
19+
<div className="flex flex-row place-items-center gap-4" key={`union-${idx}`}>
20+
<span className="break-all font-mono space-y-2">
21+
<ExcerptText
22+
excerpt={new Excerpt(member, { startIndex: 0, endIndex: member.length })}
23+
apiPackage={item.getAssociatedPackage()!}
24+
/>
25+
</span>
26+
</div>
27+
)),
28+
[item, members],
29+
);
30+
31+
return (
32+
<DocumentationSection icon={<VscSymbolArray size={20} />} padded title="Union Members">
33+
<div className="flex flex-col gap-4">{unionMembers}</div>
34+
</DocumentationSection>
35+
);
36+
}

apps/website/src/components/model/TypeAlias.tsx

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,59 @@
1-
import type { ApiTypeAlias } from '@discordjs/api-extractor-model';
1+
import { ExcerptTokenKind, type ApiTypeAlias, ExcerptToken } from '@discordjs/api-extractor-model';
2+
import { useMemo } from 'react';
23
import { SyntaxHighlighter } from '../SyntaxHighlighter';
34
import { Documentation } from '../documentation/Documentation';
45
import { Header } from '../documentation/Header';
56
import { SummarySection } from '../documentation/section/SummarySection';
7+
import { UnionMembersSection } from '../documentation/section/UnionMembersSection';
68

79
export function TypeAlias({ item }: { readonly item: ApiTypeAlias }) {
10+
const union = useMemo(() => {
11+
const union: ExcerptToken[][] = [];
12+
let currentUnionMember: ExcerptToken[] = [];
13+
let depth = 0;
14+
for (const token of item.typeExcerpt.spannedTokens) {
15+
if (token.text.includes('?')) {
16+
return [];
17+
}
18+
19+
if (token.text.includes('<')) {
20+
depth++;
21+
}
22+
23+
if (token.text.includes('>')) {
24+
depth--;
25+
}
26+
27+
if (token.text.trim() === '|' && depth === 0) {
28+
if (currentUnionMember.length) {
29+
union.push(currentUnionMember);
30+
currentUnionMember = [];
31+
}
32+
} else if (depth === 0 && token.kind === ExcerptTokenKind.Content && token.text.includes('|')) {
33+
for (const [idx, tokenpart] of token.text.split('|').entries()) {
34+
if (currentUnionMember.length && depth === 0 && idx === 0) {
35+
currentUnionMember.push(new ExcerptToken(ExcerptTokenKind.Content, tokenpart));
36+
union.push(currentUnionMember);
37+
currentUnionMember = [];
38+
} else if (currentUnionMember.length && depth === 0) {
39+
union.push(currentUnionMember);
40+
currentUnionMember = [new ExcerptToken(ExcerptTokenKind.Content, tokenpart)];
41+
} else if (tokenpart.length) {
42+
currentUnionMember.push(new ExcerptToken(ExcerptTokenKind.Content, tokenpart));
43+
}
44+
}
45+
} else {
46+
currentUnionMember.push(token);
47+
}
48+
}
49+
50+
if (currentUnionMember.length && union.length) {
51+
union.push(currentUnionMember);
52+
}
53+
54+
return union;
55+
}, [item]);
56+
857
return (
958
<Documentation>
1059
<Header
@@ -16,6 +65,7 @@ export function TypeAlias({ item }: { readonly item: ApiTypeAlias }) {
1665
{/* @ts-expect-error async component */}
1766
<SyntaxHighlighter code={item.excerpt.text} />
1867
<SummarySection item={item} />
68+
{union.length ? <UnionMembersSection item={item} members={union} /> : null}
1969
</Documentation>
2070
);
2171
}

packages/discord.js/typings/index.d.ts

Lines changed: 38 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -859,9 +859,9 @@ export interface IconData {
859859
proxyIconURL?: string;
860860
}
861861

862-
export type EmbedAuthorData = Omit<APIEmbedAuthor, 'icon_url' | 'proxy_icon_url'> & IconData;
862+
export interface EmbedAuthorData extends Omit<APIEmbedAuthor, 'icon_url' | 'proxy_icon_url'>, IconData {}
863863

864-
export type EmbedFooterData = Omit<APIEmbedFooter, 'icon_url' | 'proxy_icon_url'> & IconData;
864+
export interface EmbedFooterData extends Omit<APIEmbedFooter, 'icon_url' | 'proxy_icon_url'>, IconData {}
865865

866866
export interface EmbedAssetData extends Omit<APIEmbedImage, 'proxy_url'> {
867867
proxyURL?: string;
@@ -1989,29 +1989,29 @@ export class LimitedCollection<Key, Value> extends Collection<Key, Value> {
19891989

19901990
export type MessageComponentType = Exclude<ComponentType, ComponentType.TextInput | ComponentType.ActionRow>;
19911991

1992-
export type MessageCollectorOptionsParams<
1992+
export interface MessageCollectorOptionsParams<
19931993
ComponentType extends MessageComponentType,
19941994
Cached extends boolean = boolean,
1995-
> = {
1995+
> extends MessageComponentCollectorOptions<MappedInteractionTypes<Cached>[ComponentType]> {
19961996
componentType?: ComponentType;
1997-
} & MessageComponentCollectorOptions<MappedInteractionTypes<Cached>[ComponentType]>;
1997+
}
19981998

1999-
export type MessageChannelCollectorOptionsParams<
1999+
export interface MessageChannelCollectorOptionsParams<
20002000
ComponentType extends MessageComponentType,
20012001
Cached extends boolean = boolean,
2002-
> = {
2002+
> extends MessageChannelComponentCollectorOptions<MappedInteractionTypes<Cached>[ComponentType]> {
20032003
componentType?: ComponentType;
2004-
} & MessageChannelComponentCollectorOptions<MappedInteractionTypes<Cached>[ComponentType]>;
2004+
}
20052005

2006-
export type AwaitMessageCollectorOptionsParams<
2006+
export interface AwaitMessageCollectorOptionsParams<
20072007
ComponentType extends MessageComponentType,
20082008
Cached extends boolean = boolean,
2009-
> = {
2009+
> extends Pick<
2010+
InteractionCollectorOptions<MappedInteractionTypes<Cached>[ComponentType]>,
2011+
keyof AwaitMessageComponentOptions<any>
2012+
> {
20102013
componentType?: ComponentType;
2011-
} & Pick<
2012-
InteractionCollectorOptions<MappedInteractionTypes<Cached>[ComponentType]>,
2013-
keyof AwaitMessageComponentOptions<any>
2014-
>;
2014+
}
20152015

20162016
export interface StringMappedInteractionTypes<Cached extends CacheType = CacheType> {
20172017
Button: ButtonInteraction<Cached>;
@@ -2437,7 +2437,9 @@ export interface GuildForumTag {
24372437
emoji: GuildForumTagEmoji | null;
24382438
}
24392439

2440-
export type GuildForumTagData = Partial<GuildForumTag> & { name: string };
2440+
export interface GuildForumTagData extends Partial<GuildForumTag> {
2441+
name: string;
2442+
}
24412443

24422444
export interface DefaultReactionEmoji {
24432445
id: Snowflake | null;
@@ -3974,7 +3976,7 @@ export class ChannelManager extends CachedManager<Snowflake, Channel, ChannelRes
39743976
public fetch(id: Snowflake, options?: FetchChannelOptions): Promise<Channel | null>;
39753977
}
39763978

3977-
export type FetchGuildApplicationCommandFetchOptions = Omit<FetchApplicationCommandOptions, 'guildId'>;
3979+
export interface FetchGuildApplicationCommandFetchOptions extends Omit<FetchApplicationCommandOptions, 'guildId'> {}
39783980

39793981
export class GuildApplicationCommandManager extends ApplicationCommandManager<ApplicationCommand, {}, Guild> {
39803982
private constructor(guild: Guild, iterable?: Iterable<RawApplicationCommandData>);
@@ -4421,7 +4423,7 @@ export interface WebhookFields extends PartialWebhookFields {
44214423

44224424
//#region Typedefs
44234425

4424-
export type ActivitiesOptions = Omit<ActivityOptions, 'shardId'>;
4426+
export interface ActivitiesOptions extends Omit<ActivityOptions, 'shardId'> {}
44254427

44264428
export interface ActivityOptions {
44274429
name: string;
@@ -4776,22 +4778,16 @@ export interface AutoModerationTriggerMetadata {
47764778
mentionRaidProtectionEnabled: boolean;
47774779
}
47784780

4779-
export type AwaitMessageComponentOptions<Interaction extends CollectedMessageInteraction> = Omit<
4780-
MessageComponentCollectorOptions<Interaction>,
4781-
'max' | 'maxComponents' | 'maxUsers'
4782-
>;
4781+
export interface AwaitMessageComponentOptions<Interaction extends CollectedMessageInteraction>
4782+
extends Omit<MessageComponentCollectorOptions<Interaction>, 'max' | 'maxComponents' | 'maxUsers'> {}
47834783

4784-
export type ModalSubmitInteractionCollectorOptions<Interaction extends ModalSubmitInteraction> = Omit<
4785-
InteractionCollectorOptions<Interaction>,
4786-
'channel' | 'message' | 'guild' | 'interactionType'
4787-
>;
4784+
export interface ModalSubmitInteractionCollectorOptions<Interaction extends ModalSubmitInteraction>
4785+
extends Omit<InteractionCollectorOptions<Interaction>, 'channel' | 'message' | 'guild' | 'interactionType'> {}
47884786

4789-
export type AwaitModalSubmitOptions<Interaction extends ModalSubmitInteraction> = Omit<
4790-
ModalSubmitInteractionCollectorOptions<Interaction>,
4791-
'max' | 'maxComponents' | 'maxUsers'
4792-
> & {
4787+
export interface AwaitModalSubmitOptions<Interaction extends ModalSubmitInteraction>
4788+
extends Omit<ModalSubmitInteractionCollectorOptions<Interaction>, 'max' | 'maxComponents' | 'maxUsers'> {
47934789
time: number;
4794-
};
4790+
}
47954791

47964792
export interface AwaitMessagesOptions extends MessageCollectorOptions {
47974793
errors?: string[];
@@ -5114,14 +5110,14 @@ export interface CommandInteractionResolvedData<Cached extends CacheType = Cache
51145110
attachments?: Collection<Snowflake, Attachment>;
51155111
}
51165112

5117-
export type AutocompleteFocusedOption = Pick<CommandInteractionOption, 'name'> & {
5113+
export interface AutocompleteFocusedOption extends Pick<CommandInteractionOption, 'name'> {
51185114
focused: true;
51195115
type:
51205116
| ApplicationCommandOptionType.String
51215117
| ApplicationCommandOptionType.Integer
51225118
| ApplicationCommandOptionType.Number;
51235119
value: string;
5124-
};
5120+
}
51255121

51265122
export declare const Colors: {
51275123
Default: 0x000000;
@@ -5913,7 +5909,7 @@ export interface InteractionDeferReplyOptions {
59135909
fetchReply?: boolean;
59145910
}
59155911

5916-
export type InteractionDeferUpdateOptions = Omit<InteractionDeferReplyOptions, 'ephemeral'>;
5912+
export interface InteractionDeferUpdateOptions extends Omit<InteractionDeferReplyOptions, 'ephemeral'> {}
59175913

59185914
export interface InteractionReplyOptions extends BaseMessageOptions {
59195915
tts?: boolean;
@@ -6025,15 +6021,11 @@ export type CollectedMessageInteraction<Cached extends CacheType = CacheType> =
60256021
ModalSubmitInteraction
60266022
>;
60276023

6028-
export type MessageComponentCollectorOptions<Interaction extends CollectedMessageInteraction> = Omit<
6029-
InteractionCollectorOptions<Interaction>,
6030-
'channel' | 'message' | 'guild' | 'interactionType'
6031-
>;
6024+
export interface MessageComponentCollectorOptions<Interaction extends CollectedMessageInteraction>
6025+
extends Omit<InteractionCollectorOptions<Interaction>, 'channel' | 'message' | 'guild' | 'interactionType'> {}
60326026

6033-
export type MessageChannelComponentCollectorOptions<Interaction extends CollectedMessageInteraction> = Omit<
6034-
InteractionCollectorOptions<Interaction>,
6035-
'channel' | 'guild' | 'interactionType'
6036-
>;
6027+
export interface MessageChannelComponentCollectorOptions<Interaction extends CollectedMessageInteraction>
6028+
extends Omit<InteractionCollectorOptions<Interaction>, 'channel' | 'guild' | 'interactionType'> {}
60376029

60386030
export interface MessageEvent {
60396031
data: WebSocketData;
@@ -6094,8 +6086,9 @@ export interface MessageCreateOptions extends BaseMessageOptions {
60946086
>;
60956087
}
60966088

6097-
export type GuildForumThreadMessageCreateOptions = BaseMessageOptions &
6098-
Pick<MessageCreateOptions, 'flags' | 'stickers'>;
6089+
export interface GuildForumThreadMessageCreateOptions
6090+
extends BaseMessageOptions,
6091+
Pick<MessageCreateOptions, 'flags' | 'stickers'> {}
60996092

61006093
export interface MessageEditAttachmentData {
61016094
id: Snowflake;
@@ -6215,9 +6208,7 @@ export type PermissionResolvable = BitFieldResolvable<keyof typeof PermissionFla
62156208

62166209
export type PermissionOverwriteResolvable = UserResolvable | RoleResolvable | PermissionOverwrites;
62176210

6218-
export type RecursiveArray<ItemType> = ReadonlyArray<ItemType | RecursiveArray<ItemType>>;
6219-
6220-
export type RecursiveReadonlyArray<ItemType> = ReadonlyArray<ItemType | RecursiveReadonlyArray<ItemType>>;
6211+
export interface RecursiveReadonlyArray<ItemType> extends ReadonlyArray<ItemType | RecursiveReadonlyArray<ItemType>> {}
62216212

62226213
export interface PartialRecipient {
62236214
username: string;
@@ -6567,7 +6558,7 @@ export interface WebhookClientDataURL {
65676558
url: string;
65686559
}
65696560

6570-
export type WebhookClientOptions = Pick<ClientOptions, 'allowedMentions' | 'rest'>;
6561+
export interface WebhookClientOptions extends Pick<ClientOptions, 'allowedMentions' | 'rest'> {}
65716562

65726563
export interface WebhookDeleteOptions {
65736564
token?: string;

0 commit comments

Comments
 (0)